Backbone Model: empty attribute with get method but in attributes object - javascript

I have these lines:
console.log(JSON.stringify(this.model.attributes));
console.log(this.model.get('name'));
And this is the output:
"{"name":"ffg","key":"1c277f82-f093-d359-4cfb-febe4614a3b1"}"
""
I'm starting with Backbone.
Any ideas why the object is in the attributes but it returns empty with the get method??
EDIT:
This shouldn't affect answers, but I'm working with Phone Gap.
The 2 console.log are lines next to each other.
EDIT 2:
var temp = _(this.model.attributes).clone();
console.log(JSON.stringify(temp));
console.log(temp.name);
This logs:
{"name":"ss","questions":[],"order":0,"key":"5c35c304-4863-02c0-4d18-101c655aa4ae"}
""

I would consider logging this.model and inspecting the object into a browser (e.g. Chrome or Firefox) then look into the attributes property of the object. Make sure that the name property is defined as you intended. Also, please make sure that no event is triggered that could modify your model object.

When you fetch model, try set this yourModel.fetch({async: false})

Related

Why is my console.log in LWC showing variable data in proxy handler

I'm trying to console.log a variable's value but on the browser console instead of printing the variable (an object in my case), I am getting a Proxy container with format like
Proxy {}[[Handler]]: En[[Target]]: Array(0)[[IsRevoked]]: false
On opening the [[Handler]], I get some inner properties which contains an originalTarget property.
On expanding the originalTarget , my data is shown.
How do I get this data to show properly in console and also access it in my LWC ?
this.variableName returns value in a Proxy
If you want to view proxy data so use this :
JSON.stringify(this.caseList)
And further if you want to use it in your lwc use this:
let cases = JSON.parse(JSON.stringify(this.caseList))
console.log(cases);
I hope you find the above solution helpful. If it does, please mark it as Best Answer to help others too.
Reason : whenever we mark any Javascript object as #track, Salesforce wraps the object inside creating proxy objects.
Solution: #Rajat Jaiswal answer.

jQuery data() has an empty object, causes retrieval of data to fail

I've encountered a very strange issue with jQuery: I previously used the data() method to get an object that is stored on the element, like this:
var player = $(el).data("ytPlayer");
However, suddenly, this is returning an undefined result.
Looking at the $(el) object during setup and initialization of the page, I see it in the list of properties:
and at this point, if I call $(el).data("ytPlayer") it works as expected and I get the object.
But later in the lifecycle of the page, when the call to data() fails, I see this in the list of properties for that element:
There's an empty object, and also you can see my desired object right below it, but I can't seem to get to it. If at this point I call $(el).data() with no parameters, I get an empty object as well.
Is there any way to trace where this empty object is coming from, and/or any way to force jQuery to ignore it to get to the object I need?
It turns out the best way (at least for me) to troubleshoot this problem was to remove all scripts until the call to data() worked again, then gradually add them back one at a time until it failed.
this allowed us to isolate the offending script and fix it.

Object.assign not working as expected

I have one object called bookings, and inside it I have several properties, and i want extend with Object.assign, like this:
let data = Object.assign(booking, {
hiw: event.hiw[booking.locale],
tip: event.tip[booking.locale],
start: moment(event.start).format('L')
});
But when I print the data, the result will be the same object from the source (booking), so hiw, tip and start will be ignored, but... if I try to do:
let data = Object.assign({}, {
hiw: event.hiw[booking.locale],
tip: event.tip[booking.locale],
start: moment(event.start).format('L')
});
This will work perfect.
My question is: what am I doing wrong here? Why can't I extend booking and I can extend the empty object?
That's definitely not a problem with async code, when i try to extend booking, he already exist with all properties inside.
I also was trying to use underscore extend method, and the behavior is exactly the same.
Mongoose documents (model instances) are special: they will only print properties that are present in the schema.
If properties aren't defined there, they won't show up when you console.log() them (and also not if you convert the document to a plain JS object with obj.toObject()).
This means that using Object.assign() will only work if you assign properties that are also present in the schema. Any properties that aren't declared will not be shown (nor saved to the database).
If your intention is to use the document for output, you should convert it to a proper JS object first before assigning to it:
let data = Object.assign(booking.toObject(), {
hiw : event.hiw[booking.locale],
tip : event.tip[booking.locale],
start : moment(event.start).format('L')
});

Struggling for Backbone syntax in collection events

I have a collection, I can do this successfully ('this' is the collection instance):
this.on('change:username', function(model,property,something){
// model is backbone model that changed
// property is the property that changed (username in this case)
// something is some empty mystery object that I can't identify
}
however what I want to do is this:
this.on('change', function(model,property,something){
// model is backbone model that changed
// ***how can I read the properties that changed here?***
// something is some empty mystery object that I can't identify
}
the problem is that in the second case, I can't get the property that changed...maybe that's because it's potentially multiple property changes all at once.
How can I capture that properties that changed in the second case? is this possible?
The only way I know how to do this would be
this.on('change', function(model, something){
// something object is unidentifiable
var changed = model.changed; //hash of changed attributes
}
so my other question is: what is that mystery object "something"? It is just an empty object...?
You have a couple of options you can use in general change events:
Backbone.Model#hasChanged: This will allow you to see if a model attribute has changed in the context of this change event. If so, you can get its new value and apply it to the view (or whatever other context) as needed.
Backbone.Model#changedAttributes: This will allow you to get all changed attributes since the last set() call. When called with no parameters, it is a defensively cloned copy of the changed hash; you can also pass in a hash of parameters and get only what is different about the model relative to that set of key/value pairs.
Backbone.Model#previous: This will allow you to get the previous value of a model attribute during a change event.
Backbone.Model#previousAttributes: This will allow you to get all the previous values of a model during a change event. You could use this to completely undo a change (by calling set with the result of this function) if you wanted to.
By the way, the third parameter of the change:attr event (and the second of change) is an options object, which can be useful if you want to specify custom values that can be read by your event handlers. There are also a number of standard options Backbone will handle specially. See the documentation for Backbone.Model#set for more information on the specific options, and take a look at the Backbone event list to see the callback signatures expected when those events are triggered.

Ember computed property doesn't fire when bound to deeply nested property

This JSBin isolates a problem I ran into in my code. I have a hierarchy of embedded models and a computed property (data) that is supposed to fire whenever a value at the very bottom of the chain changes (symbol). The example displays the property directly as well as the result of the computed property. A button changes the value on click. You'll see that it updates the property but the computed property doesn't fire. Why doesn't selectedAllocation.positions.#each.instrument.symbol work to trigger the computation when any instrument.symbol changes?
If the example seems contrived, it's only because I tried to abstract something that is more complex in reality, e.g. there is more than just one object in these arrays and data is necessary because another library expects a simple JS object in a particular format.
Note that #each only works one level deep. You cannot use nested forms
like todos.#each.owner.name or todos.#each.owner.#each.name.
http://emberjs.com/guides/object-model/computed-properties-and-aggregate-data/
You'll need to create an alias to bring symbol up one level (Not a coffeescript guy, hopefully you can read through the hacking, the positions alias below is for kicks and giggles, makes no difference).
App.Position = Ember.Object.extend({
instrumentSymbol: Em.computed.alias('instrument.symbol')
})
App.IndexController = Ember.ArrayController.extend
selectedAllocation: null
positions: Em.computed.alias('selectedAllocation.positions'),
data: (->
#get("positions").map (position) ->
symbol: position.get "instrumentSymbol"
).property "positions.#each.instrumentSymbol"
...
http://jsbin.com/bivoyako/1/edit

Categories

Resources