What's the difference between model.attributes and JSON.stringify - backbone.js

What's the difference between model.attributes and JSON.stringify ?
Maybe some prpberties, methods do not fall ?
var Todo = Backbone.Model.extend({});
// We can then create our own concrete instance of a (Todo) model
// with no values at all:
var todo1 = new Todo();
// Following logs: {}
console.log(JSON.stringify(todo1));
console.log( todo1.attributes)

I am stealing #Daedalus's answer here but he is right, JSON.stringify returns a string representation of the model - no two ways about it.
Are you sure you don't meant model.toJSON which returns a shallow copy of attributes?
var artist = new Backbone.Model({
firstName: "Wassily",
lastName: "Kandinsky"
});
artist.set({birthday: "December 16, 1866"});
// Object {firstName: "Wassily", lastName: "Kandinsky", birthday: "December 16, 1866"} "object"
console.log(artist.attributes, typeof artist.attributes);
// Object {firstName: "Wassily", lastName: "Kandinsky", birthday: "December 16, 1866"} "object"
console.log(artist.toJSON(), typeof artist.toJSON());
// {"firstName":"Wassily","lastName":"Kandinsky","birthday":"December 16, 1866"} string
console.log(JSON.stringify(artist), typeof JSON.stringify(artist));
Fiddle: http://jsfiddle.net/ferahl/ftb83yuo/

Related

setState an array and object

How do you setState an object and an array at the same time after passing id and data to a function? Because comment is not part of an array, I'm getting confused.
this.state = {
tasks: [
{ firstName: "boris", lastName: "Johnson", id: uuid() },
{ firstName: "Mary", lastName: "Whithaker", id: uuid() }
],
comment: "This is a comment message"
};
updateTask(id, task, comment, additional) {
const updatedProject = this.state.tasks.map(t => {
if (t.id === id) {
return {
...t,
firstName: task,
lastName: comment
};
}
return t;
});
this.setState({ tasks: updatedProject, comment: additional });
}
Your State is an object.
In that object there are two fields, tasks and comment.
Tasks is an array of objects, those objects have firstname, lastname and id fields.
Comment is a string.
When that code is doing setState at the end, it is creating a new object (see the {}), and then giving it the updatedProject array for tasks, and then the additional string for comment.
That whole object is then set. The array and string are values of fields in that object.

Store array to session storage with ngStorage

I could use some help on how i could store an array to the session storage:
So i have a json object that returns this
Object
Objectauthority: "USER_ROLE"
email: "1#1"
enabled: true
firstName: "1"
id: 1
lastName: "1"
password: "$2a$10$qPjtVDxkCh3KaE2mr0.ZeuyyjceLy7JPVmelttVf7uekSQq01fZ9u"
but it has also returns a client list
clientList: Array[7]
city: "Brussel"
company: "John Doe's coffee shop"
country: "Belgium"
...
This is the angularjs code
$http.get('/api/getuser').success(function(data) {
$scope.userdata = data;
console.log(data)
//Here we add all the stuff we need to the sessionStorage
$sessionStorage.userid = data.id;
$sessionStorage.userEmail = data.email;
$sessionStorage.sampleString = "This is a sample string";
//But how can i store the array to the sessionStorage ?
//Is something like this possible ?
$sessionStorage.clientArray[] = data.clientList[]
})
Ok i have it working i only needed to remove the [] So something like this works :
$sessionStorage.clientArray = data.clientList

Angular Shorthand on $scope for saving data

is there any shorthand for something like this?
var data =
{
name: $scope.admin.name,
email: $scope.admin.email,
roles: $scope.admin.roles
};
Usually after i query and input to model i can just use like this:
$scope.admin = {
name: value1,
email: value2,
roles: value3
}
Edited:
My exact question inside var data how can i make it more simple like above without keep typing "$scope.admin".
Thanks
If you do not want a deep copy with angular.copy(), but just want to type less signs in code, you can do
var x = $scope.admin;
var data =
{
name: x.name,
email: x.email,
roles: x.roles
};
If you need to copy all the properties, use angular.copy:
angular.copy($scope.admin, $scope.user)
If you need to pick a subset of properties, a library like lodash might be useful. You would use the pick function:
$scope.admin = {
firstname: 'John',
name: 'Doe',
email: 'john#mycompany.com',
roles: ['sysadmin']
};
$scope.user = _.pick($scope.admin, ['name', 'email', 'roles']);
// -> {name: 'Doe', email: 'john#mycompany.com', roles: ['sysadmin']}

Sorting a nested array from model in Ember?

So I have a model in Ember that is generating a hash with three objects. One of the objects is an array of objects with another array inside each object. I need to sort this innermost array, but I am having trouble doing so.
Here are my models.
App.Person = DS.Model.extend ({
first_name: DS.attr('string'),
last_name: DS.attr('string'),
age: DS.attr('string'),
gender: DS.attr('string'),
innerMostArray: DS.hasMany('innerMostObject')
});
App.innerMostObject = DS.Model.extend ({
person_id: DS.belongsTo('person'),
attr1: DS.attr('string'),
attr2: DS.attr('string')
});
Here is my Route
App.NestedArrayRoute = Ember.Route.extend({
model: function(params) {
return Ember.RSVP.hash({
object1: this.store.find('object1', params.object1_id),
people: this.store.all('person'),
object3: this.store.all('object3')
});
},
afterModel: function(model, transition) {
model.people.forEach(function(item, index, enumerable){
var innerMostArray = item.get('innerMostArray');
var sortedArray = innerMostArray.sortBy('attr1', 'attr2');
});
model.people.update();
}
});
I know that I am nowhere near doing this right but I just don't know how to sort this nested array. I've seen examples of array controllers, but I don't know how to use one to sort this nested array. If anyone could give an example of how to do this it would be very helpful. Thank you.
I agree with Kalmans answer, but I suggest you do this sorting with built-in methods to save you trouble:
App.Person = DS.Model.extend({
name: DS.attr('string'),
fruits: DS.hasMany('fruit', {async: true}),
fruitSorting: ['title', 'color'],
sortedFruits: Ember.computed.sort('fruits', 'fruitSorting')
});
I forked his example here: http://emberjs.jsbin.com/manutu/1/edit?html,js,output
One way to do this is to create a computed property on the model as follows:
App.Person = DS.Model.extend({
name: DS.attr('string'),
fruits: DS.hasMany('fruit', { async: true }),
sortedFruits: function(){
var fruits = this.get('fruits');
return fruits.sortBy('title', 'color');
}.property('fruits.#each.title', 'fruits.#each.color')
});
Working example here

How to display all attributes of model subclass on first initialization?

Problem
When a child model is initialized for the first time, only defaults of the child are set as attributes.
When a second(and all subsequent) child is being initialized, the attributes of child display defaults of child and it's parent.
Fiddle
var Parent = Backbone.Model.extend({
defaults: {
name: "john",
lname: "smith",
age: 30,
language: "english",
location: "belgium"
}
});
var Child = Parent.extend({
defaults: {
hobby: "doing nothing",
age: 24,
occupation: "student"
},
initialize: function () {
this.constructor.__super__.initialize.apply(this, arguments);
_.defaults(this.defaults, this.constructor.__super__.defaults);
console.log(this.attributes);
}
});
attributes of child initialized for the first time :
var child1 = new Child();
child1.attributes :
hobby: "doing nothing"
age: 24
occupation: "student"
attributes of same Child class, initialized for the second time:
var child2 = new Child();
child2 attributes:
age: 24
hobby: "doing nothing"
language: "english"
lname: "smith"
location: "belgium"
name: "john"
occupation: "student"
Question
Why are not all defaults(child's and parent's) are being set as attributes when a child model is initialized for the first time ?
Because i've to display a Backbone.Collection inside a <ul> and every model's attributes are configurable through a html form inside each <li>. But because of this problem, i can't get to all attributes of the first model in the collection.
You're modifying the Child class's defaults object when the first object is instantiated, during its initialize method. At that point, the Backbone.Model constructor has already used defaults to fill in the attributes for that object, so it will only affect subsequent instantiations.
Take a look at Backbone.Model:
var Model = Backbone.Model = function(attributes, options) {
var defaults;
var attrs = attributes || {};
options || (options = {});
this.cid = _.uniqueId('c');
this.attributes = {};
_.extend(this, _.pick(options, modelOptions));
if (options.parse) attrs = this.parse(attrs, options) || {};
if (defaults = _.result(this, 'defaults')) {
attrs = _.defaults({}, attrs, defaults);
}
this.set(attrs, options);
this.changed = {};
this.initialize.apply(this, arguments);
};
initialize is the very last step, after the defaults have been set, so modifying defaults at that point won't do anything for the current object.
To get it to work how you want, modify defaults after you declare the class, rather than during initialize:
Child.prototype.defaults = _.defaults(Child.prototype.defaults, Parent.prototype.defaults);
Working example

Resources