Backbone Collection got wrong Models - javascript

how can I rewrite the Backbone Collection fetch() function to get a specific part in my JSON?
The json I get looks like this:
{
"success":true,
"data":[
{
"id":1,
"title":"asdf",
"link":"http://www.xx.cc/image/asdf/",
"date":1439993443000
},
{
"id":2,
"title":"qwer",
"link":"http://www.xx.cc/image/qwer/",
"date":1439993091000
}
]
}
And my simple Backbone Script:
var myCollection = Backbone.Collection.extend({
url: 'url.to/my/rest/'
});
myCollection.fetch();
console.log(myCollection);
the Problem here is, that the collection I get got a length of 1 with 1 model in in it. When I log that collection and open "n -> models -> 0 -> attributes -> data" I find all my objects within the JSON data array.
But I need the objects of tha "data"-array as models in my collection. So Far I found no solution to this problem so may someone got the right idea for me?

Supply your collection description object with a parse function, as described in the docs:
var myCollection = Backbone.Collection.extend({
url: 'url.to/my/rest/',
parse: function(data) {
return data.data;
}
});
This method extracts the relevant part from the server's response and fill a collection based on this part.

Related

NodeJS not able to process array of objects received via POST

I'm having this collection of objects which are inside a html text area:
{"name":"John", "lname":"Doe","company":"example company","email":"johndoe#example.com"},{"name":"Katie","lname":"Jake","company":"example company","email":"katie#example.com"},
...
...
...
Is there a way to send the whole collection to node js and iterate through it to get values of objects?
My AJAX code:
$.ajax({
type: "POST",
url: "https://example.com/nodeapp",
data: '['+document.getElementById("list").value+']',
success: function(data) {
console.log(data);
}
});
I tried to do a foreach on req.body, but it doesn't seem to work:
var arr = req.body;
arr.foreach(element=>{
console.log(element.email);
})
Gives the error:
TypeError: arr.foreach is not a function
At first , you have to parse the body by using JSON.parse() function .
Like this :
var arr = JSON.parse(req.body);
arr.forEach(element=>{
console.log(element.email);
});
The javascript's foreach also defined as arr.forEach(...) not arr.foreach(...) .
I found my problem! Incase someone is stuck with the same thing, the whole thing was a string:
'[{"name":"John", "lname":"Doe","company":"example company","email":"johndoe#example.com"},
{"name":"Katie","lname":"Jake","company":"example company","email":"katie#example.com"},
...
...]'
Which was considered as one property in JSON which has no value while the server received it. Pretty much like this:
{
"<<the array in string format>>" : ""
}
How I fixed this was, I pushed the objects separately into a new array and sent it to server with JSON content type. (Which was an actual array of objects)

SAPUI5 OData - How to create new entry with association to existing entity?

I am currently using SAPUI5/OpenUI5 to consume and modify OData Services.
I want to create a new product entry over an HTTP POST Request and have problems to properly config the associations to a category. For developing reasons I am using a reference OData Service with this metadata. The Product already has the NavigationProperty to the right Category EntrySet.
<NavigationProperty Name="Category" Relationship="ODataDemo.Product_Category_Category_Products" FromRole="Product_Category" ToRole="Category_Products"/>
I am using the following JavaScript code in my controller:
var oCategory = oModel.getData("/Categories(0)");
var oEntry = {};
oEntry.ID = "10";
oEntry.Name = "Beer";
oEntry.Category = oCategory;
oModel.create("/Products", oEntry, {
method: "POST",
success: function(data) {...},
error: function(response) {...}
});
The product is successfully created /Products(10) but the relation to the existing category /Products(10)/Category is not working properly. Instead a new category with the same ID and information is created (is this meant with 'deep insert'?) but I want to use the elected category (of course).
Do I have to reference the category differently or can I create the associations manually somehow? Shouldn't the OData Service check if the category ID already exists and then use the existing entry?
Is there any best practices for such cases?
It's important to note that you are using an OData V2 service. Yes, by building the request the way you are doing it, you are actually doing a deep insert.
If you think about it, it makes sense, because you would not need to send the whole category information to just link the new product to the exiting category. What if you would change something in the category data? Should a deep insert result in an update?
In any case, OData v2 has something called "links" (see the OData terminology - www.odata.org). Basically each "association" between entities is represented through such a link. You can manage these links separately from the entity (e.g. you can remove and create links between existing entities; without having to change the entity itself - see the OData v2 operations, chapters 2.9 to 2.12).
Depending on the data format that you are using (by default, JSON if you are using sap.ui.model.odata.v2.ODataModel), you can create entity links in the same time when creating new entities. Check out this answer: https://stackoverflow.com/a/4695387/7612556.
In a nutshell, you would have to write something along the lines of:
oModel.create("/Products", {
ID: "10",
Name: "Beer",
Category: {__metadata: {uri: "/Categories(0)"}}
}, {
method: "POST",
success: function(data) {...},
error: function(response) {...}
});

Ajax issue when loading json-file

I am saving a json string to local storage with setItem and get it back with getItem. This works, but when loading the same json string via ajax the object is becoming different.
Here is the original object in google-chrome browserconsole:
collection_parameter: Object
->OFFLINE: Array s
->_byId: Object
->models: Array[500]
..
Here is the stringified json (getItem, setItem) local-storage:
{"OFFLINE":[{ "data_type":"OFFLINE",
"Number":"1",
"val_param_1_2_3":0 },
{..},
{..} ]
}
When I am saving the above json-string in a file e.g. called Test.json and load it via ajax the object is not the same anymore.
Here the ajax call:
$.ajax({ //Laden
url: 'Test.json',
method: 'GET',
dataType: 'json',
success: function(recieved_json_parameters) {
collections_parameter=recieved_json_parameters;
}//end success
});//end ajax
The new object collection_parameter in google-chrome is now:
collection_parameter: Object
->OFFLINE: Array [500]
The additional nodes are missing. What can I do to get the exact same object-type as above??
UPDATE1: This is how I create the original json:
var collections_parameter = { OFFLINE: Backbone.Collection.extend() }
collections_parameter.OFFLINE = new collections_parameter.OFFLINE(json);
In order to store a Backbone Collection, you should save the raw data the collection has, which you can get with toJSON(): (the returned value is an array of objects)
collection.toJSON() /* store the object returned by this function */
(In your case, I think the collection is collection_parameter.OFFLINE)
After retrieving the JSON representing the data, create a new Backbone Collection initialized with it:
collection = new MyCollection(json)
where MyCollection is the subclass of Backbone.Collection you're using, or Backbone.Collection itself, and json is the object you retrieved.
The reason for this is that you need to store the actual data represented by the Collection. The Collection object itself provides you functions for accessing and changing the underlying data, but it's not the data itself, and therefore it should not be serialized and stored. After retrieving the raw data, you create a new Collection that will provide you the various functions for accessing the data.

Dynamically load my 'IDs' into my Backbone Collection?

Ok, I have got this working with answers posted on another question here, but I am trying to do something a little more. I have a Backbone set up as follows,
var MyModel= Backbone.Model.extend();
var MyCol = Backbone.Collection.extend({
model : MyModel,
url: '/GetData/2',
parse: function(response) {
return response;
}
});
var stuff = new MyCol;
stuff.fetch({
success: function (collection, response) {
console.log(response);
}
})
Now this code fully works. Now to explain, the URL is set with PHP Slim, which returns JSON encoded data, where will be four key/pair groupings, for example:
<code> { id; XX, data: XX, another:XX, last:YY } </code>
This data is being received form a database, now how should I do this dynamically? By that I mean that on the URL' line in my collection, it passes 2 as the current ID. How can I get backbone to call each ID I need, there are currently 6 listing in the database. So I need it display/console log (currently for testing) all 6 inputs, so how would I change that ID input to 1-6? Should I just use a for loo? I really want something that will not need to change if say lists are removed form the database or more are added?
The end aim is for this JSON data is for it to load into my Backbone view, which is a template for a form.
All help most welcome,
Thanks
Glenn
P.S Sorry if my spelling is off I am dyslexic, also may not have explained things right, so let me know and I will improve my wording, thanks.
EDITS
This is what I am working with now ::
var AdminModel = Backbone.Model.extend({
defaults: {},
urlRoot: '/GetData'
});
var AdminColModel = Backbone.Collection.extend({
model : AdminModel,
url: '/',
parse: function(response) {
//console.log(response);
return response;
}
});
var stuff = new AdminColModel;
stuff.fetch({
success: function (collection, response) {
console.log(collection);
}
})
This does not console log anything at all? But the PHP is set up and working fine, so when you go to /getData you get a whole list if all the rows in the database. When you view /getData/X <- X is the id number, that will return just that rows ID data.
Glenn
You should not make an individual request for each model in your collection at the collection level. The url you have set for your collection should request all of the models by default. So instead of it being:
'/GetData/2'
It should instead be:
'/GetData'
Then on the server side you should ensure that the GetData action returns all MyModels.
You can then write overrides for GetData that take parameters to either return an individual model, or filter the results. You will be particularly interested in the individual model retrieval, which should be the URL used at the model level. in fact, you already have this action, as you are using it (incorrectly) to retrieve the collection. This is the action associated with the /GetData/2 URL. This action should be the one used when you call fetch inside the model, not the collection.
Hopefully this helps.
Post Edit
Adding some code to assist.
var AdminModel = Backbone.Model.extend({
urlRoot: '/GetData'
});
var AdminCollection = Backbone.Collection.extend({
model : AdminModel,
url: '/GetData'
});
var wholeCollection= new AdminCollection();
// the fetch method on the collection uses the AdminCollection.url property
wholeCollection.fetch({
success: function (collection) {
console.log(collection); // will output collection object to console
}
});
// this model does not exist in any collection
var modelOutsideCollection = new AdminModel({}, { id: "2" });
// because the model is not in a collection, fetch uses the AdminModel.urlRoot proeprty
modelOutsideCollection.fetch({
success: function (model) {
console.log(model); // outputs a single model with id of 2 to collection
}
});
So... The way you seem to be doing things is going to make it really hard (if even possible) to work with Backbone.
What you should have is an API endpoint (e.g.) "getData" that will return all models:
[
{id: 1, name: "asdflj"},
{id: 2, name: "lsdfkjg"},
// etc.
]
Then, you define "getData" as the collection's url. For each model in the collection, Backbone will automatically compute the model instance's url as (e.g.) "getData/2" (if the model's id is 2).
In other words, you'd need to change your API to have:
getData -> return all models
getData/2 -> return model with id 2

Trying to pull data from parse and render with underscore.js getting empty frields

Trying to pull data from parse.com and use underscore.js I tried using this to build a table of the data. When I run it with hard coded json it works but when I try running it with pulled data returns an empty table.
Parse.initialize("", "");
var allDeals = Parse.Object.extend("Deal");
var query = new Parse.Query(allDeals);
query.find({
success: function(results){
var deals = JSON.stringify(results);
var template = $("#usageList").html();
$("#target").html(_.template(template,{deals:deals}));
},
error: function(error) {
alert('something was wrong');
}
});
Thanks in advance!
Like #mu said it would be easier to see whats in results..
But I have run into this with Parse before. Taking a guess.. You can try this
$('#target').html(_.template(template, { deals: results.models }));
"results" is a backbone collection and "models" holds the array of objects you are after.
Presumably you're getting a JavaScript object of some sort in results in your success callback. Then you serialize that to a JSON string with:
var deals = JSON.stringify(results);
That leaves you with a string in deals and your template probably doesn't know what to do with a string, it probably wants an object or whatever was in results in the first place. Try skipping the stringification and just feed results straight into the template:
$('#target').html(_.template(template, { deals: results }));

Categories