I'm having an odd error where a backbone where function (Titanium Alloy, kinda homogeneous) returns empty while the fetch method returns a list of models. Ive checked over and over again, I tried putting the where function in the success callback of the fetch method but STILL it results in an unresolvable error
Alloy.Collections.favorites.fetch({
success: function(collection) {
console.log(JSON.stringify(collection));
console.log(self.get('id'));
var favorite = collection.where({
jobId: self.get('id')
});
console.log(JSON.stringify(favorite));
});
The above output is:
[{"jobId":5162179,"dateAdded":1414590144,"candidateId":99,"id":19},{"jobId":5161302,"dateAdded":1414588983,"candidateId":99,"id":17},{"jobId":5161437,"dateAdded":1414588785,"candidateId":99,"id":16}]
5161437
[]
How can the above happen? How can somebody reproduce this? Is the collection being occupied or is it a bug within Titanium Alloy? This process is part of a databind on a view (view A) and this exact code works on a different part where the only difference is that view A is not directly influenced by changes in the collection.
Any help? Is this even possible with backbone? I cant get my head around this
APPARENTLY the .where function strictly compares 2 values (=== operator) and the id i gave was in the form of a string while the id within the collection was an integer. Too bad the backbone documentation doesnt state this information
Related
I am making my first app using Parse.com for database storage, and I am using the Parse JavaScript SDK to make use of this database.
I am trying to populate a list of items from one of my database tables, and this table contains a field which is a pointer to an object of another class/table. I need to retrieve a field from this object in order to display the information properly.
However, Parse seems to require me to request each of these objects separately from my main query on the table. Anyway, so I make the request and have a success callback which uses jquery's .html() to set the contents of a div which is id'd by the id of the retreived object.
The problem is, after the work is done, the div is rendered empty. Although, oddly, I tried using calls to alert to get the contents of each div within the success callback, and the contents was not only correct after I had called .html() but also before I called it. Though, that's probably down to JavaScripts asynchronous function calls.
Here is the function in question:
function updateBudgets() {
var Budget = Parse.Object.extend("Budget");
var query = new Parse.Query(Budget);
query.equalTo("User", Parse.User.current());
//query.include(["Budget.Category"]); //I tried this to include the category object with the query response, but it didn't seem to work
query.find({
success: function(result) {
var opt = "<h2>Budgets</h2>";
var category, id;
for(var i = 0; i < result.length; i++) {
category = result[i].get("Category");
category.fetch({
success: function(cat) {
alert($('#' + cat.id).html());
$('#' + cat.id).text(cat.get("Name"));
alert($('#' + cat.id).html());
}
});
opt += makeBudget(category.id, parseFloat(result[i].get("Amount")/100), result[i].get("Balance"), result[i].id);
}
$('#budgets').html(opt);
}
});
}
I tried what the documentation seemed to suggest was the equivalent of an SQL JOIN operation using the .include() function on my query, but it didn't seem to work at all.
So, what I would like to know is either how I can debug my JavaScript such that I can get around this strange behaviour with .html() or how I can properly do this JOIN style operation with Parse. What Documentation I have found doesn't really go into a whole lot of detail.
I would be very grateful for any help.
Please consider the following "test guide" more as comment than an answer, because it just contains some console.log statements instead of an actual answer for your problem.
Anyway below are some issues I'd try to checkout:
do you receive an answer from the server following query.find
check is data fetched (inner query) from the server
check if category data is received successfully following fetch query
check if element with category id is found
error handling added for fetch and query
Also I noticed that you are using .text() method for setting the value. I think it'll work fine as long as the element in question is not a form input element. If that's the case, you probably have to you use .val() method.
The console.log test print outs that I added can be found at this Fiddle for updateBudgets() function. (Fiddle updated) I hope this helps :-)
I'm currently experimenting with Knockout JS just to get the hang of the library and all of it's capabilities and I appear to have run into a wall with handling external JSON data.
In the Codepen below I have a dummy observable array which is working fine. Commented out below that is the actual JSON data I want to experiment with. It takes an external feed using $.GETJSON and maps that to filter the results to extract only the data I want to use in my HTML template.
My problem is that I can't seem to get the external JSON to bind to the HTML as I always get 'tracks' is not defined, or sometimes even an empty console (which is always helpful).
Can anybody point me in the right direction of how to handle external JSON? I've done searching around and I can't see much info dedicated to handling external JSON.
http://codepen.io/anon/pen/Hnamf
Looking at your codepen, it isn't entirely clear how you want this to work, but it certainly can be made to work. Just as a quick demo, I moved your $.getJSON inside your init function so that it can actually have access to the view model and then in the callback set what you are getting to the property self.tracks. Since you were binding "tracks", I changed "title" to "tracks", but you can obviously do whatever makes sense to you:
$.getJSON('http://api.soundcloud.com/users/guy-j/tracks.json?client_id=YOUR_CLIENT_ID', {limit: 200}, function(data) {
vm.tracks($.map(data, function (track) {
return {
artwork: track.artwork_url,
duration: track.duration,
permalink: track.permalink_url,
listens: track.playback_count,
stream: track.stream_url,
track: track.title
};
}));
});
http://codepen.io/anon/pen/HAkhy
Let's say you have a VB.Net web method with the following prototype:
Public Function HelloWorld() As DataTable
Let's say you have that returned to you in ordinary JavaScript/Ajax. How would you get individual rows out of it, and how would you get individual fields out of those rows (at least assuming it comes from an SQL query - I'm not sure if it makes a difference)? I'm not casting it into any particular type before it gets passed to the success function. To illustrate what I'm talking about, it would be kind of like doing this in AS3:
for each (var table:Object in pEvent.result.Tables) {
for each (var row:Object in table.Rows) {
ac.addItem(row["id"]);
}
}
except that I'm not necessarily looking to loop through them like that - I just want some way to get the information out of them. Thanks!
EDIT: For example, say you have the following function in a VB.Net web service:
<WebMethod()> _
Public Function Test() As DataTable
Return DBA.OneTimeQuery("SELECT id FROM visits WHERE id = 13")
// returns a one-row, one-column DataTable with the id field being set to 13
End Function
How would you be able to get 13 out of it once it gets into the JavaScript that's calling the web method? Everything I try just says "[object]".
You do not want to return a DataTable object in your web method. The best approach would be to develop a REST web method that returns JSON that represents the data you want to return, as JavaScript will be able to work with JSON directly. Here is a QA the directs you on how to do this. This is if you are using WCF, which it appears you are. I find it better to use ASP.NET Web API for RESTful web services.
Whenever I console.log() a Backbone.js Collection, Google Chrome's console shows the letter "d" unlike the typical "Object" log-entry in Safari or Firefox. Is there a difference?
Also, whenever I console.log() any sub-item in a Collection (e.g., console.log(exampleCollection.models)), I get an empty array. Am I doing something wrong?
Code:
(function($) {
var Item = Backbone.Model.extend({
defaults: {
"sku":"",
"brand":"",
"model":"",
"picture":"placeholder.jpg"
},
url: function() {
return this.id ? 'products/' + this.id : 'products';
}
});
var Items = Backbone.Collection.extend({
model: Item,
url: "products"
});
var items = new Items;
items.fetch();
console.log(items); // shows "d" in Google Chrome along with typical
// object-like drop-down options
console.log(items.models); // shows "[]" empty array in console
})(jQuery);
I'm still new at Backbone but I think Jon Saw is right. All of Backbone's models, collections, views show up as d and it's littered all over the minified code. If you see d, it's a good sign you can manipulate it like Backbone objects can.
As for the empty array, I'm suspecting that your server side code isn't returning the collection correctly. Can you post an example of how you're handling that request and what you're sending back?
I think I remember running into a similar problem and the solution was to make sure it's returning nice json data and that the content-type was application/json. But my memory is hazy.
EDIT: You might want to play with the success and error callbacks available to fetch(), to shed more light on the situation.
EDIT2: This past post might be related to your issue - Getting data to and from server with Backbone
EDIT3: I posted a full backbone example from creating models, adding them to a collection, fetching extra models in the form of a collection from server and adding them to the existing collection (rather than resetting). It has views and subviews mixed in but some of the aspects seemed similar to this question so I am including the reference:
Keeping track of old part of collection and new part
working with backbone, I was seeing a problem where some data was being left blank, so I wrote this to try to see what was going on.
console.log('actions.models', this.model.actions.models)
console.log('actions.models.length', this.model.actions.models.length)
console.log('first actions.models', this.model.actions.models[0])
the output
actions.models [ Action ]
actions.models.length 0
first actions.models undefined
if I add a setTimeout of say 2 seconds to this code I get
actions.models [ Action ]
actions.models.length 1
first actions.models Action
I don't get how this could happen. I don't know where to start looking or even what would be helpful to post for you guys to look at.
If anyone can help point me in the right direction I would appreciate it. Thanks very much.
Are you loading the models via an Ajax function, like fetch? If so, you can't count on data being loaded until the Ajax function's callback is invoked, e.g.
actions.fetch {success: -> console.log actions.models.length}
Not sure what you are trying to do, but anyway.. When you dump objects to the console log, be aware of the fact that since objects are passed by reference, whatever you get from inspecting it in the log will be whatever the object ended up being. Assuming you want to log the state of an object you should probably try to serialize it when logging. For instance console.log "mymodel: ", JSON.stringify(mymodel.attributes).
Also be aware that to access backbone models, you would typically use name = mymodel.get('name'), or for a collection item = mycollection.get('someid').
If you post some testable code and what you are trying to accomplish, I'm sure somebody with a clue will be able to help you out.