How to deal with AngularJS's $$hashKey? - javascript

I'm using AngularJS to code an app's front end, which consumes and store data from Backendless.
So far so good, the thing is that when I try to store changes I get errors because $$hashKey property added by AngularJS.
To make a long story short, my problem is that if I get an object from Backendless, I make changes on it with AngularJS and then I try to save the modified object, Backendless API seems to expect an object with same attributes, and since AngularJS adds stuff such as $$hashKey, I get the errors.
So, my question is, how do I get rid of $$hashKey ?,
I've read similar questions here but:
I'm not dealing with JSON objects, so unless I can convert to json to clean attributes and then 'build' the object again, this approach is not very useful.
They're not considering nested objects, i.e. removing attributes from attribute objects
The answers don't consider making a deep copy before making any changes and then update such a copy before saving, which is an alternative I'm considering but I'm not quite sure if it's the best one.
Any hint or comment is very appreciated.
Thank you in advance.

Related

Howto get OpenUI5 Binding Information

I need to figure out what objects within a OpenUi5 JSONModel are bound to at least one UI component.
I want to check what objects are bound of the model and then get only new values of the bound objects from an embedded device. With other words I do not want to get all available information of a embedded device via web request if some of them are currently not visible / bound on the Ui.
Does anybody have an idea how I could figure this out using javascript.
I already saw that the JSONModel has a property called aBindings that lists all current UiBindings, but I wonder if this is the right way to get that information.
Thanks!
It looks like this is your first question here, so welcome to StackOverflow!
Although it is expected that you already try out the code for which you seem to have issues and then post it here with the errors or expected results, I will still try to help you out.
To get answers to your question, I would suggest you to read through the Data Binding section under Get Started: Setup and Tutorials of the SAPUI5 Demokit. This includes,
Creating a model
Property binding
Binding paths and formatting values
Once you get the basics right, you will see that with the concept of Two-way Binding, the model is already updated with the new values that you are looking for, if it's changed in the UI and vice-versa.
Also, if you are looking for a particular object or property, you can directly query the model instead of worrying about to which control it is binded.
For example this.getView().getModel("myModel").getProperty("/view/visible") will return the current value of the property "visible" regardless of which control it is binded to.
If my answer totally misses your question, please elaborate on your concerns and we can explore it further.

How to bind to view model object properties?

We are building a form-based app that has a complex object with many levels of nested properties.
So far, I have created a simple experiment with a single view model with one object. The experiment has fields that are bound to object properties, which successfully display the data. However, when changing the fields, the object does not seem to be updated.
What should I do to make sure form input propagates throughout the view model and into the template?
You need to use getter method in app.js as below,
get swaggerString() {
console.log(this.swagger);
const swaggerStringified = JSON.stringify(this.swagger);
return swaggerStringified;
}
In your HTML, change method to property,
${swaggerString}
Updated your GIST,
https://gist.github.com/anonymous/3b85820d66c2dfbf0f770208a7c8b63f
Hope this helps!
What are you planning to do in the real app?
The accepted answer only answers how to solve your problem as posted in the gist. I'm guessing your real app doesn't need to display JSON data.
If you are just wanting to display deeply nested object properties, then that is simple, you simply bind to those properties themselves. See here: https://gist.run/?id=5af5c22be4b49c0e3fef327e3d8b986b
<pre>
{
"name": "${swagger.name}",
"version": "${swagger.version}"
}
</pre>
You can even go arbitrarily deep in to an object tree, e.g. ${foo.bar.baz.ball.foop}.
The thing to understand is that Aurelia observes for changes to whatever you tell it to observe. When you tell it to simply observe an property that is an object, it can only watch for changes to the property itself. This means it will only see a change if you assign a different object to the property. It does not watch every property on the object for changes for performance reasons (and also due to Object.observe being cancelled).
All hope is not lost, though. Please respond with some specifics and I'll try to help you out better.

Deep comparison and getting values in angular

I do not have time to create a fiddle right now, but will definetely do so tomorrow.
Basically my problem is caching a data model retrieved from a restful get endpoint and comparing to a new model returned by a restful updated endpoint in order to be able to highlight the changed values in the UI.
The way I handled this is by using underscore's each() and angular.compare() methods in order to loop through a collection and compare it object key by object key.
However this feels wrong and I have problems in getting the updated key name.
Is there a better, accepted way to do this as I cannot find anything anywhere, just a bunch of people generally asking the same question and getting answers like: 'Use a watcher and underscore/angular methods, it is easy'.
For what I have understand, what you are trying to do is the correct way to see it.
You have to compare object by object.
To help you between the old collection and the new one, a watcher is not a bad answer. In fact the angular watcher can give you the old collection and the new one as parameters. So all you got to do is make a check object by object. And had a special treamenton the different values.
Hope this can help you.

Getter / Setter or direct reference?

Learning Ember.js and have a reasonable understanding of getters and setters (accessors) through Ruby and Java.
In Ember/Javascript, I seem to have a very serious lack of understanding. For instance in my controllers/models, I don't have a clue whether to use object.set(property,value) or refer them directly object.property = 'value'
As an example, in my earlier question (How to get Model values in Controller), part of working answer was to use object.name instead of object.get('name'). It worked but I miss the basic understanding.
Would appreciate some clarifications.
The rule is: You should always use .get()/.set() when you are in your .js-files. When you are in your templates (.hbs or other) you should not (you can't do it).
If you access a property via myObj.myProp it will work for regular properties, but computed ones won't. If you set a property via myObj.myProp you can still get the value back, but bindings and observers won't be notified that it has changed and won't updated properly.
This is a design decision by the Ember team which allows for efficient bindings/observers instead of doing dirty-checking of all bound/observed properties (which is what Angular currently does).
I made a small jsbin showing this. Three values are bound initially, the button then changes one and logs it into the console (so make sure to have the console open), the binding isn't updated but the value can be retrieved. It then tries to get a computed property via myObj.myProp which returns undefined and then the regular way.
http://emberjs.jsbin.com/cipapaxevi/2/
Also, as a side note. If you want a property thats on a child object to what you have you can access it via myObj.get('myProp.myOtherProp') instead of doing myObj.get('myProp').get('myOtherProp'). It saves you from the worry that myProp could return null or undefined.
That's the way Javascript works and it's one of its disadvantages. It doesn't have public/private proprieties nor methods. Therefore, we should rely on good comments in the code.
I am not an expert in Ember, but when I face the similar problems in JS I usually look at the source code of the library to see how it's constructed and then make a decision. That's why probably js libraries are usually shipped with both min and dev versions.
However, if the object has special methods to access its properties then they are there for a reason, so use them instead of the direct access to the properties. As I said above, in Js you can't make properties be private or protected.

How to correctly access properties of a Sencha model?

There appear to be a number of different ways how to access properties of a Sencha (Touch) model. However, I don't seem to be able to find proper documentation of which is the "correct" way of doing it.
Model creation
var model = Ext.create('MyApp.model.MyModel', {
name: value,
foo: bar,
...
})
Property access
model.get('name') or model.set('name', newValue)
model.data.name or model.data.name = newValue
model.raw.name seems to always return a string no matter what the data type in the model definition is?
Let's sort this all out:
get and set methods are the intended accessors for model field values.
model.data is the object that stores the client side model value, that is that have been converted from the data received from the server proxy using the fields configuration (type, convert method, etc.).
model.raw is the raw data that was received from the server proxy, before it was converted to client side application domain model values. You should avoid using it, or you will tie yourself to your proxy/server.
model['name']: as you've said, it doesn't work. Don't hope for it to come back (I don't even really understand that it worked at one point).
Now, which one should you use? Clearly, the last two ones are already out of the match.
The model.data object should give you the expected result in most cases (see bellow), and should give you a marginal performance gain other calling a function.
However, IMO you should always prefer to use the getters and setters, for two reasons.
First, it might happen that someone in your team (or you from the past) decides that the getter/setter is a good point to add some custom logic. In this case, bypassing the accessor by using the data object directly will also bypass this logic, and yield unpredictable result.
Secondly, getters and setters make it really easier to debug some situations, by making it easy to know from where modifications of the model values are coming. I mean, if one day you were to ask yourself "f**k, why is my model field value changing to this??". If all the code uses the getters, you'll just have to put a breakpoint in there, and you'll catch the culprit hand in bag. On the other hand, if the incriminated code uses the data object directly, you'll be stuck to do a whole project search for... You can't tell exactly what... data.name =? data['name'] =? name:? etc.
Now that I think about it, there is yet another reason. A deprecated one apparently. But the data object name used to be customizable using this persistenceProperty option. So, in some cases, the data object won't even be available, and code doing model.data.name instead of model[model.persistenceProperty].name would crash, plain and simple.
Short answer: use the accessors.

Categories