What is safe method to perform `Object.assign` when using AngularJS? - angularjs

Basically I would like to perform Object.assign to get copy of my data, without anything that AngularJS attached in the past, it attaches now, or may attach in future versions.
Sure I can delete such property as $$hashKey after assignment but this approach is totally fragile, on the other hand I could manually construct the object with fields I want but this on the other hand is tiresome (and also fragile if I change definition of my source object).
Is there something solid in between?

There are no other properties as $$hashKey, it is one of a kind.
All of Angular object helpers are aware of this property and remove it at the end of the operation. angular.extend is a direct Angular counterpart of Object.assign and should be used instead.

angular.copy seems to be helpful in this case

Related

Backbone attributes clone or pass in directly from this?

I need all of the attributes in one model. Is it considered good practice to give them as follows:
this.functionName(this.attributes);
from within the model, i am confused due to what it says in the backbone API under:
http://backbonejs.org/#Model-attributes
it writes:
"to retrieve and munge a copy of the model's attributes, use _.clone(model.attributes) instead."
But I do not follow, should I clone them instead? and if so, why? I do not see any difference in the debugger between the cloned and this.attributes version
Thank you in advance
The keyword here is "munge".
From wiki
Mung or munge is computer jargon for a series of potentially destructive or irrevocable changes to a piece of data or a file.Common munging operations include removing punctuation or html tags, data parsing, filtering, and transformation.
If you simply need a reference to the model attributes, what you're doing is fine, no need to overthink it.
You should clone the attributes when you plan on changing the data and don't want to affect the original attributes.

What's the preferred way to go about using backbone with non-crud resources?

New to backbone/marionette, but I believe that I understand how to use backbone when dealing with CRUD/REST; however, consider something like results from a search query. How should one model this? Of course the results likely relate to some model(s), but they are not meant to be tied to said model(s).
Part of me thinks that I should use a collection using a model that doesn't actually sync with a data store through the server, but instead just exists as a means of a modeling a search result object.
Another solution could be to have a collection with no models and just override parse.
I assume that the former is preferred, but again I have no experience with the framework. If there's an alternative/better solution than those listed above, please advise.
I prefer having one object which is responsible for both request and response parsing. It can parse the response to appropriate models and nothing more. I mean - if some of those parsed models are required somewhere in your page, there is something that keeps reference to this wrapper object and takes models from response it requires via wrapper methods.
Another option is to have Radio (https://github.com/marionettejs/backbone.radio) in this wrapper - you will not have to keep wrapper object in different places but call for data via Radio.

In an AngularJS expression is there a way to compare a scope value to a value in another library?

I'm creating a directive around a third party library, to go in a form, where the option chosen in a select drop-down will bring up a different set of form elements.
In the parent element of each subset of form elements I'm trying to use an expression similar to this: ng-if="myScopeObj.val === ThirdParty.CONSTANT_VAL". I came to realize it's not working because the "ThirdParty" library isn't on the scope.
Should I just assign the library to a variable on the scope, or is there some pattern that can address this? It seems like creating isThis() or isThat() functions for every constant in the library wouldn't be a great solution.
Should I create a service to wrap the third party library and then inject it into the directive? Though I'd still need to put the injected service on the scope. Would that be overkill for a library that doesn't access remote APIs? I don't think it'd need to be mocked for testing, anyway.
You're correct that you do need to get the value on the $scope somehow in order for it to be usable. And you're correct that one of the primary benefits of wrapping in a service is that you can mock the library. Another benefit of wrapping in a service is self-documentation. As someone else (or yourself at a later time) looking at your code, I could be confused as to where ThirdParty is coming from. Working in Angular, the assumption is that all dependencies are injected, and breaking convention comes at a cognitive cost. Having a service also can make it easier to swap out the underlying library later for a different implementation. Anyway, your simplest fix is:
$scope.ThirdParty = ThirdParty;

backbone.js accessing model attributes within model - this.attribute VS this.get('attribute')?

From my understanding the attributes of a Backbone.js model are supposed to be declared as somewhat private member variables by saying
this.set({ attributeName: attributeValue })
// accessing the value
this.get('attributeName');
But when I am writing functions whitin the actual model it seems much simpler to say like this:
this.attributeName = attributeValue;
// accessing the value
this.attributeName;
Also I would assume that the latter version would be faster to process since it doesn't go through backbone.js's event management.
So I was wondering how you pros do with attributes that are primarily used internally in the model. These are the attributes that one would actually want to be a bit shielded from the outside so having them exposed like in the latter example maybe isn't right still. When I have been looking at examples for the backbone.js view which doesn't have get and set methods it seems fine to do like in the second example. So is there any nice rule of thumb when to use get/set(attribute) or this.attribute when coding within the model? Or maybe an example of a model that makes this clearer?
When to use model.get(property) and model.set(...)
You should use get and set to access the model's data. This means any attributes that are part of the model's serialized representation that is retrieved using fetch and persisted using save.
When to use model.attributes.property
Never.
You should always use get, and especially set, instead of accessing the model.attributes object directly, although I've seen conflicting opinions about this. I believe there is a contract between a model and it's consumers, which guarantees that the consumer can be notified of any changes to the model's data using the change event. If you modify the internal attributes object directly, events are not sent and this contract is broken. Backbone events are very fast, especially if you don't have any listeners attached to them, and it's not a point that benefits from over-optimization on your part.
Although accessing the attributes directly instead of get is quite harmless on it's own, it should be avoided so the attributes object can be considered totally, completely private.
If you absolutely need to prevent some change triggering events, you can use the silent:true option: model.set({key:val}, {silent:true}). This does break the aforementioned contract, and even Backbone's own documentation gives the following caveat:
Note that this is rarely, perhaps even never, a good idea. Passing through a specific flag in the options for your event callback to look at, and choose to ignore, will usually work out better.
When to use model.property
Any properties which are not data, i.e. temporary state variables, calculated properties etc. can be attached directly to the model entity. These properties should be considered temporary and transitive: they can be recreated upon model initialization or during its lifetime, but they should not be persisted, whether public or private. A typical naming convention is to prefix private properties with the _ character as follows:
this._privateProperty = 'foo';
this.publicProperty = 'bar';
Never is an incomplete answer.
Sometimes you want access to the collection of model attributes - whatever those attributes might be. Consider a utility method to perform calcs on attributes, format them for output, etc.
A convenient way to do this is to access model.attributes
Consider one alternative, below:
var attributesNames = ['foo', 'bar', 'baz'];
var attributes = _(attributesNames ).map(function(attr) { return model.get(attr); });
callSomeUtilityMethod(attributes);
Two problems:
We've introduced coupling in the "attributeNames" collection. What if that list changes?
We've lost the association of name/value. We could rewrite the map above, but it becomes more work.
In this scenario, it's much more convenient to do something like this:
callSomeUtilityMethod(model.attributes);

Question using Ext's update() instead of dom.innerHTML

I have a question concerning the performance, reliability, and best practice method of using Extjs's update() method, versus directly updating the innerHTML of the dom of an Ext element.
Consider the two statements:
Ext.fly('element-id').dom.innerHTML = 'Welcome, Dude!';
and
Ext.fly('element.id').update('Welcome, Dude!', false);
I don't need to eval() any script, and I'm certain that update() takes into consideration any browser quirks.
Also, does anyone know if using:
Ext.fly('element-id').dom.innerHTML
is the same as
d.getElementById('element-id').innerHTML
?
Browser and platform compatibility are important, and if the two are fundamentally the same, then ditching Ext.element.dom.innerHTML altogether for update() would probably be my best solution.
Thanks in advance for your help,
Brian
If you do not need to load scripts dynamically into your updated html or process a callback after the update, then the two methods you've outlined are equivalent. The bulk of the code in update() adds the script loading and callback capabilities. Internally, it simply sets the innerHTML to do the content replacement.
Ext.fly().dom returns a plain DOM node, so yes, it is equivalent to the result of getElementById() in terms of the node it points to. The only subtlety to understand is the difference between Ext.fly() and Ext.get(). Ext.fly() returns a shared instance of the node wrapper object (a flyweight). As such, that instance might later point to a different node behind the scenes if any other code calls Ext.fly(), including internal Ext code. As such, the result of a call to Ext.fly() should only be used for atomic operations and not reused as a long-lived object. Ext.get().dom on the other hand returns a new, unique object instance, and in that sense, would be more like getElementById().
I think you answered your own question: "Browser and platform compatibility are important, and if the two are fundamentally the same, then ditching Ext.element.dom.innerHTML altogether for update() would probably be my best solution." JS libraries are intended (in part) to abstract browser differences; update is an example.
#bmoeskau wrote above, update() provides additional functionality that you don't need right for your current problem. Nevertheless, update is a good choice.

Resources