Getting raw reponse after fetching backbone collection - javascript

I have an json response from the server like this for backbone collection
{
"Heading":[
{
"heading1":"heading1",
"heading2":"heading2",
"heading3":"heading3",
"heading4":"heading4",
"heading5":"heading5",
"heading6":"heading6",
"heading7":"heading7"
}
],
"Data":[
{
"column1":98310,
"column2":"spl",
"column3":"sreedhar Laptop",
"column4":"LAPTOP",
"column5":"ACTIVE",
"column6":true,
"column7":"c56e4b92-debe-4c8e-9472-bbb6a322346d"
},
{
"column1":196609,
"column2":"NLP",
"column3":"NLP testing..",
"column4":"LAPTOP",
"column5":"ACTIVE",
"column6":true,
"column7":"7fe2efd4-b93b-4ea8-98a4-7a75d77efb77"
},
{
"column1":262146,
"column2":"venky",
"column3":"venkyLaptop",
"column4":"DESKTOP",
"column5":"INACTIVE",
"column6":false,
"column7":"2e512b95-e2b3-414c-8b40-3bd00b626ae4"
}
]
}
So What I want is to pass only the Data aray for the collection so I have used parse method like this
Customer = Backbone.Collection.extend({
model: customerModel,
url: function () {
return Config.serviceURL("getCusData");
},
parse: function (response) {
return response.Data;
}
});
This is working perfectly but Now I want that Heading array also after I apply fetch So how can I get this Heading array on calling fetch??

There's no rule that says that parse can't stash parts of response in this. For example:
parse: function(response) {
this.headings = response.Heading;
return response.Data;
}
Then later the collection can look at this.headings to see the response.Heading values.
Demo: http://jsfiddle.net/ambiguous/k9aUa/
If you're using other methods (such as reset) to populate your collection then you might need to override those to reset this.headings.

Related

Why is there multiple copies of the collection nested inside the models?

I'm creating a collection in backbone js, after this fetch data from the backend, I print in the console inspector in chrome, but something caught my attention in the attributes.
The collection has models, and inside of each model has an attribute called "collections" and inside of this has a attribute call "models" and so on
I'm not interacting yet with the views, only create a collection and fetch de data.
This is what happens in the console:
This is the code that I'm using for the parse:
var TablesCollections = Backbone.Collection.extend({
model: Table,
url: '/api/tables',
parse: function(response) {
if(response.procced == 7) {
return response.data;
} else {
return "An error has trigger";
}
},
initialize: function() {
this.fetch();
}
});
And this is the models:
var Table = Backbone.Model.extend({
defaults: {
'title': '',
'titlestring' : '',
'schema': {},
'manageschema': {},
},
parse: function(response){
if(response.proceed){
if(response.proceed == 4){
response.data.schema = JSON.parse(response.data.schema);
response.data.manageschema = JSON.parse(response.data.manageschema);
response = response.data;
}
} else {
if(response.schema != 'Na'){
response.schema = JSON.parse(response.schema);
}
if(response.manageschema != 'Na'){
response.manageschema = JSON.parse(response.manageschema);
}
}
return response;
},
});
Why is there multiple copies of the collection nested inside the models?
This is normal. Each Backbone Model that is added to a collection has a reference to the collection that it belongs to. (accessed via this.collection where this is the model)
What you see in the console is a circular reference. The collection has models. Each model has a reference to the collection. That same collection has the same models which have the same reference to the collection, etc...
Model's constructor documentation:
The model.collection property is normally created automatically when you first add a model to a collection.
In your screenshot, you can see that cid: "c8". This is the client id which Backbone adds to models and collections. This shows you that it's the same model reference each time.

How do you search and return a specific index of a JSON resource in AngularJS?

I have a json file of events setup like this:
{
2: {
sched_conf_id: "38",
title: "Coffee Break",
},
3: {
sched_conf_id: "39",
title: "registration",
},
}
I setup and angular factory like this:
.factory('eventFactory', ['$resource',
function($resource) {
return {
query: function(event_id) {
return $resource('/assets/events.json', {}, {
query: { method: 'GET', params: {id:event_id}, isArray: false }
}).query();
}
}
}
])
and lastly I have my angular controller which calls the query method from the factory with the id being the id from the url:
.controller('eventCtrl', function($scope, $routeParams, eventFactory) {
var eventId = $routeParams.event_id;
$scope.eventData = eventFactory.query(eventId);
})
The return data seems to be just the entire events.json file rather than just the specific id I want to query for in the parameters. In the params I am trying id but that is obviously not correct. Using this setup how can I return just the data from event_id: 2?
Assuming your production scheme is going to be fetching just a static file that doesn't do anything with arguments passed in, you need to extract the record you need after it's returned from the server.
Basically, you're requesting something like http://yourhost.com/assets/events.json?event_id=3 and if it's just a static file, the server can't do anything with that parameter. In practice, I would think you'd actually be requesting a response from a web service that can handle that, in which case your client-side code would probably work as-is.
In this specific case, however, I would think that you could handle this with an interceptor. Something like this:
.factory('eventFactory', ['$resource',
function($resource) {
return {
query: function(event_id) {
return $resource('/assets/events.json', {}, {
query: { method: 'GET', isArray: false,
interceptor: {response:
function(data){ var d = JSON.parse(data);
return d[event_id];
}
}
}
});
}
}
}
])
I don't have an environment set up to test this at the moment, but I think it should work. I have a couple places in my own code where I do something similar, for other reasons.

Ember data find() methods returns array, but I need a single record

I'm using Ember and Ember-Data.
App.InviteRoute = Ember.Route.extend({
model: function(params) {
return this.store.find('user', { invitation_token: params.token });
}
});
This pings my server and returns a single User record, however the this.store.find() method returns an DS.PromiseArray.
I just need to know how to fetch a single object using Ember-Data using an arbitrary field.
In my template:
<h1>This is the invite template.</h1>
<p>{{id}}</p>
<p>{{email}}</p>
This should work:
App.InviteRoute = Ember.Route.extend({
model: function(params) {
return this.store.find('user', { invitation_token: params.token }).then(function(users) {
return users.get('firstObject');
});
});

Is it possible to use repeating params in ngResours query

I'm using Angular with ngResource and i've got an api url:
GET http://my.com/rest/items?inState=TRANSIENT&inState=FINAL
How could I do query with two (not uniq) params 'inState'?
This is my Resource factory:
.factory('Resource', function ($resource, REST_URL) {
return {
items: $resource(REST_URL + 'rest/items',
{},
{
get: {method: "GET", params: {inState: '#inState'}}
})
};
})
And this is the way I'm call it:
//GET http://my.com/rest/items?inState=TRANSIENT
Resource.items.get({inState: 'TRANSIENT'}, function (data) {
//...
}, function (responce) {
//...
});
This is works but the problem is in how I'm send params - as object: {inState: 'TRANSIENT'}
I cannot write something like
{inState: 'TRANSIENT', inState: 'FINAL'}
beacuse of fields must be uniq
P.S. I know that it may be done with $http.
That's how to do this:
{inState: ['TRANSIENT', 'FINAL']
Example:
//GET http://my.com/rest/items?inState=TRANSIENT&inState=FINAL
Resource.items.getHistory({inState: ['TRANSIENT', 'FINAL']}, function (data) {
//...
}, function (responce) {
//...
});
Not sure if you have control over what is consuming the parameters, but if you do you could try passing the parameters as an object with an array of objects in it, like this:
{ states : [{inState : 'TRANSIENT'}, {inState : 'FINAL'}]}
Then just iterate through the states array and check each inState property.

Nested Model in Backbone.js

I want to map JSON having hierarchical structure onto Model. I can map the data at a top hierarchy onto Model. However, I can't map it onto Model which nested the element which I nested.
JSON
{
"attr1":"data1",
"chi1": {
"attr1":"chi1_data"
},
"list1":[
{"name":"name1"},
{"name":"name2"}
]
}
JavaScript
var Child2 = Backbone.Model.extend({
fun1:function() {
alert("this is Child2");
}
});
var List1 = Backbone.Collection.extend({
url: "list1",
model: Child2,
fun1:function() {
alert("this is List1");
}
});
var Child1 = Backbone.Model.extend({
});
var Root1 = Backbone.Model.extend({
url: "sample.json",
defaults : {
list1 : new List1,
chi1 : new Child1,
}
});
var View1 = Backbone.View.extend({
el: "#friends",
events: {
"click button": "sample"
},
initialize: function() {
this.root1 = new Root1();
},
sample: function() {
this.root1.fetch({
success: function(model) {
// this is success
alert(model.get("attr1"));
// this is error
alert(model.get("list1").fun1());
// this is error too.
model.get("list1").each(function(attr) {
alert(attr.fun1());
});
},
error: function(model, res) {
alert("error: " + res.status);
}
});
},
});
You might want to take a look at this plugin.
http://documentup.com/afeld/backbone-nested/
Might not be exactly what you want, but it could at least point you in the right direction.
The other thing you can do is override the parse method on your model...
parse: function(resp){
// And setup the model using the raw resp
// The resp data is your json from the server and will
// be used to setup the model. So overriding parse, you can
// setup the model exactly they way you want.
return resp;
}
thank you jcreamer.
backbone-nested plugin seems to be different from what I want to do.
I can realize the nest of the model. In using parse function.
// it is able to get "chi1_data"
new Child2(JSON.parse(JSON.stringify(resp["chi1"]))).get("attr1")
// it is able to get "name2"
new Child2(JSON.parse(JSON.stringify(new List1(JSON.parse(JSON.stringify(resp["list1"]))).get(2)))).get("name")
I found Backbone-relational plug in. I will try this
https://github.com/PaulUithol/Backbone-relational

Categories

Resources