Window object appearing in array - javascript

When I run the code below, jQuery, repeatedly, puts a Window object in my array (and I'm sure the JSON doesn't include any references to the Window object). Is there any way to run this and keep the Window object out of my array?
Thanks
$.getJSON("../php/return_network_data.php",
function(fetch_data){
$.each(fetch_data, function(){
var index = this.id;
node_array[index] = paper.circle(this.xpos_init, this.ypos_init, 10).attr({"fill" : "#ff0000"})
$.each(node_array, function(){
console.log(this);
});
});
}
);

This should work..have to add index,value in each function
$.getJSON("../php/return_network_data.php",
function(fetch_data){
$.each(fetch_data, function(index,value){
var index2 = value.id;
node_array[index] = paper.circle(this.xpos_init, this.ypos_init, 10).attr({"fill" : "#ff0000"})
$.each(node_array, function(index,value){
console.log(value);
});
});
}
);

I'm not sure what paper.circle does exactly (is this raphael?), but I think it might be one of two things:
Removing the attr function from the paper command and adding it later.
node_array[index] = paper.circle(this.xpos_init, this.ypos_init, 10);
Adding key, value to the function in each:
$.getJSON("../php/return_network_data.php", function(fetch_data){
$.each(fetch_data, function(key, value){
var index = value.id;
node_array[index] = paper.circle(value.xpos_init, value.ypos_init, 10).attr({"fill" : "#ff0000"})
$.each(node_array, function(){
console.log(this);
});
});
});
Or possibly both?

Related

JavaScript console.dir and runtime

I'm trying to use an object for javascript to hold my main elements etc. And my object will grab contents from the HTML elements. And I'm trying to use console.dir to see if my data is grabbed correctly.
The issue is, console.dir shows all values at once instead adding each element one by one. I'm using jQuery's each function.
Here is the fiddle ;
https://jsfiddle.net/365dzdhh/9/
Here is the code ;
(function(jQuery) {
'use strict';
window.DOER = {
saver:function(e){
e.preventDefault();
var sel = jQuery('.sel');
var data = {};
sel.find('.sell-me').each(function(){
//Shouldn't this show values one by one instead of all in one at once?
console.dir(data);
data = window.DOER.grabber(jQuery(this), data);
});
console.dir(data);
},
grabber:function(el,data){
data[jQuery(el).attr('id')] = jQuery(el).val();
return data;
},
init:function(){
jQuery(document).on('click', '.save-it', this.saver);
}
};
}($));
$(document).ready(function(){
window.DOER.init();
});
If you check the console, you'll see the log in the line "15" shows every details each time. Shouldn't it add each value by looping one by one? Am I missing something here?
I think this will give you the console info you want. console.dir(this) on line 15.
(function(jQuery) {
'use strict';
window.DOER = {
saver:function(e){
e.preventDefault();
var sel = jQuery('.sel');
var data = {};
sel.find('.sell-me').each(function(dataForEach){
//Shouldn't this show values one by one instead of all in one at once?
console.dir(this);
data = window.DOER.grabber(jQuery(this), data);
});
console.dir(data);
},
grabber:function(el,data){
data[jQuery(el).attr('id')] = jQuery(el).val();
return data;
},
init:function(){
jQuery(document).on('click', '.save-it', this.saver);
}
};
}($));
$(document).ready(function(){
window.DOER.init();
});

Extend jQuery Plugin with additional function / override function

I need to extend a jQuery Plugin (https://github.com/idiot/unslider) in order to add additional behavior with another public method.
(function(){
// Store a reference to the original remove method.
var originalMethod = $.fn.unslider;
// Define overriding method.
$.fn.unslider = function(){
// Execute the original method.
originalMethod.apply( this, arguments );
console.log( "Override method" );
function test() {
console.log("test called");
}
this.each(function() {
// Operations for each DOM element
console.log("each dom element?");
}).data('unslider', {
// Make test accessible from data instance
test: test
});
return this;
}
})(jQuery);
I already managed to make the public method accessible when calling
var slider = $('#slider');
slider.data('unslider').test();
However, I want to keep the old behavior of unslider anyways, but extend the Plugin with another function. Does anyone have an idea?
I created a fiddle, so you can check whats happening:
My new function gets called, but the old ones are gone:
http://jsfiddle.net/b2os4s7e/1/
If you look at the source of unslider, you can see it stores the Unslider instance inside the data:
// Enable multiple-slider support
return this.each(function(index) {
// Cache a copy of $(this), so it
var me = $(this),
key = 'unslider' + (len > 1 ? '-' + ++index : ''),
instance = (new Unslider).init(me, o);
// Invoke an Unslider instance
me.data(key, instance).data('key', key);
});
In your code you're overwriting this object with your own object. However, the slider expects there to be an Unslider instance. So what you want to do is get this instance and then extend it with your own functions:
var key = $(this).data('key');
var obj = $(this).data(key);
obj.test = function() { console.log('Working!'); };
See http://jsfiddle.net/b2os4s7e/2/
Just define:
$fn.unslider2 = function() { ... }
With any name and behaviour you like.
For extend JQuery should use .fn.extend
(function($){
$.fn.extend({
helloworld: function(message){
return this.each(function(){
$(this).click(function(){
alert(message);
});
});
}
});
})(jQuery)
the object .fn.extend is used for extend funcionality of jQuery
Thanks for your answers! I did it this way:
(function($){
var originalMethod = $.fn.unslider;
$.fn.extend({
unslider: function(o) {
var len = this.length;
var applyMethod = originalMethod.apply( this, arguments );
var key = applyMethod.data('key');
var instance = applyMethod.data(key);
// Cache a copy of $(this), so it
var me = $(this);
if (instance) {
instance.movenext = function (callback) {
return instance.stop().to(instance.i + 1, callback);
};
instance.moveprev = function (callback) {
return instance.stop().to(instance.i - 1, callback);
};
}
return applyMethod.data(key, instance);
}
});
})(jQuery)
The key was to address the data attribute as sroes suggested.
Moreover i needed to apply the original method, since i need the old methods.

Can't set scoped variable in $.post callback

I have the following type of structure:
(function(){
var objects = [];
$('button.one').on('click', function(){
fetchObjects = function(objects) {
$.post("/fetchObjects")
.done(function(data){
objects = data;
console.log(objects.length);
});
}
fetchObjects(objects)
});
$('button.two').on('click', function(){
console.log(objects.length);
});
})();
You can see I have a variable objects that is local to this function. Initially its empty. When I click button.one I wish to populate objects with the returned value from some ajax request. It appears to work, however when clicking button.two, the objects variable is still an empty array.
Why isn't objects available in the jQuery callback?
I've also tried this approach but with the same results:
function callback(data) {
facilities = data
}
$.post("/fetchObjects")
.done(function(data){
callback(data);
});
What am I missing here? Please don't tell me to make "objects" global.
I don't know why you're passing objects as parameter. The following should work fine I think. Please let me know if you're trying to achieve something else.
(function(){
var objects = [];
$('button.one').on('click', function(){
fetchObjects = function() {
$.post("/fetchObjects")
.done(function(data){
objects = data;
console.log(objects.length);
});
}
fetchObjects()
});
$('button.two').on('click', function(){
console.log(objects.length);
});
})();
Let's simplify the code a bit. You have essentially this:
var objects = [];
fetchObjects = function(innerObjects) {
var data = ['a','b'];
innerObjects = data;
console.log(innerObjects.length);
};
fetchObjects(objects);
console.log(objects);
(I've changed the other objects variable's name just for clarity; the issue is the same even if it had the same name.)
When you call the function, innerObjects contains a reference to objects so modifying it would change the original array as well. But when you do
innerObjects = data;
now instead of modifying the array you're replacing the reference with something else. innerObjects "points" to data instead of objects and the original variable remains unchanged.
To make it work you'd need to loop through the data array (assuming it'll always be an array) and assign the contents to the objects reference one by one. This way you'll keep the original reference and modify the original array.
var objects = [];
fetchObjects = function(innerObjects) {
var data = ['a','b'];
for( var i = 0; i < data.length; i++ ) {
innerObjects[i] = data[i];
}
console.log(innerObjects.length);
};
fetchObjects(objects);
console.log(objects);
Or, in your actual code:
(function(){
var objects = [];
$('button.one').on('click', function(){
fetchObjects = function(objects) {
$.post("/fetchObjects")
.done(function(data){
for( var i = 0; i < data.length; i++ ) {
objects[i] = data[i];
}
console.log(objects.length);
});
}
fetchObjects(objects)
});
$('button.two').on('click', function(){
console.log(objects.length);
});
})();

Passing variables between functions in Javascript

I have this code:
collection = (function() {
function collection(removeLinkTitle){
this.removeLinkTitle = removeLinkTitle || 'delete';
}
collection.prototype = {
removeLinkTitle: this.removeLinkTitle,
init:function(){
...some code...
this.deleteCollectionForm();
},
deleteCollectionForm:function(){
var removeFormA = $(''+this.removeLinkTitle+'');
linkLi.append( removeFormA );
removeFormA.on('click', function(e) {
e.preventDefault();
linkLi.remove();
var index = collectionHolder.data( 'index' );
collectionHolder.data( 'index', index - 1 );
});
}
};
return collection;
})();
The thing is that the var removeForm returns its value only the frst time it loads, the following times it returns undefined.
I don't want to pass the variable as an argument so, is it there any other way to do this?
Thanks !!
i think this is not really the problem, the one thing that is undefined is the, removeLinkTitle, try this:
return new collection;
so you hit your constructor, or set some other value with:
return new collection("delete item");

how to access object's member through a method which filled by another method?

I know the title is a little bit confusion, here is the details:
Say I have a custom object defined in javascript, and there is a public member defined in it:
function Test()
{
this.testArray = [];
}
And I have two methods for this object, one is read out some xml file and filled into the array:
Test.prototype.readXML = function()
{
var self = this;
$.get('assest/xml/mydata.xml', function(d){
$(d).find("item").each(function(){
var item = new Item;
item.ID = ($(this).attr("ID"));
item.body = ($(this).find("body").text());
});
self.testArray.push(item);
});
}
And another function, which will display the content into the HTML page.
Test.prototype.appendInfo = function()
{
var i;
for (i=0; i<testArray.length;i++)
{
$('#testdisplay').append(testArray[i].ID +"<br />");
$('#testdisplay').append(testArray[i].body = "<br /");
}
}
However, the display function continue gives me error that the testArray is not defined. I'm not sure where is the problem, since I put the display function behind the reading function. I expect that the data will be stored in the array and could be accessed anytime I need them.
Hope some one will kindly help me about this! Thank you!
}
}
So I notice two problems with your code.
First when you do your ajax call you need to pass a deferred back to the user. Since ajax calls are async it may not finish right away.
So your readXML function should do this. It should return the jquery get.
Test.prototype.readXML = function() {
var self = this;
return $.get('assest/xml/mydata.xml', function(d){
$(d).find("item").each(function(){
var item = new Item;
item.ID = ($(this).attr("ID"));
item.body = ($(this).find("body").text());
});
self.testArray.push(item);
});
}
Next you your second function append was just missing some context.
Test.prototype.appendInfo = function() {
var i;
for (i=0; i<this.testArray.length;i++) {
$('#testdisplay').append(this.testArray[i].ID +"<br />");
$('#testdisplay').append(this.testArray[i].body = "<br /");
}
}
So your code should look like this.
var mytest = new Test();
mytest.readXML().done(function(){
mytest.appendInfo();
}).fail(function(){
// put some fallback code here
});
Updated:
Added additional this's.
There is no testArray in your appendInfo() function, that's why it says it's not defined. You should use this.testArray instead.
Every time you want to use a variable declared inside your scope, but outside the function you are using, you must use this.yourVariable

Categories