Where would you instantiate nested components using Closure Library? - javascript

Closure library offers a basic life cycle for Components:
Instantiation
Rendering/Decoration
Document Entering
Document Exiting
Disposal
I'm focusing on the first two. About design patterns, when is it better to instantiate a nested component in the first steps?
Instantiation: needs to be hold on a property till added through addChild and consumes memory before necessary. Anyways, it allows to do some dependency injection or better initialization because of the parameters it receives.
Rendering/Decorating: messes up the dom creation, which can be already complicated because of the references of other objects it needs. It also would need the instantiation parameters previously stored in some property. Anyways, holds the instantiation till is needed.
Maybe a separated method called after instantiation which wraps the rendering? I'm asking because Closure Libray book and documentation don't talk about this.

Doing some refactorying and trying to split logic, came to the following conclusion:
The best option I've found so far is to create the components inside the createDom method:
Normally, the parameters needed for components involve the data they present. My arquitecture uses DAO, which means all data objects are conveniently connected. Subcomponents usually need some other data objects which are accessible by the parent's DAO. Since the parent object is needing this DAO, it's ok to store it on a property for the use inside the createDom.
The other thing is that instantiation and rendering in the createDom component, theoretically, only needs two lines, which isn't a mess.
Again, it's the best possible solution to increase cohesion.

Related

this.watch vs. on Mutate for handling changes in a backdraft watchable

In a backdraftjs component with watchable 'titleString', is there any difference/preference between
this.watch('titleString', this.handleTitleStringChange);
and
onMutateTitleString(newTitle, oldTitle) {
...
}
The onMutate has the benefit that it remembers the old value (oldTitle) but this.watch() is maybe a little easier to find in code since it contains the word titleString -- where for onMutate you have to know to search for the camelcased-and-concatenated version.
Are there any other reasons to use one or the other?
Great question.
To begin...a minor clarification in the question: both methods are provided the new value and old value. See the docs for a watcher.
The main difference is that onMutateproperty-name is a member function. As such, it is unconditionally applied immediately after the actual mutation to the underlying memory slot occurs and before any watchers are applied. In essence, it is an extension of the framework's mutation machinery for a particular property in a particular class that contains the WatchHub mixin. It is used to define/enforce a behavior that is part of the definition of the class. As such, note also onMutateproperty-name can be overridden in subclasses (because, structurally, onMutateproperty-name is a method, and, heuristically, the behavior is part of what defines the mental model of the class).
All that said, it is certainly possible to accomplish most of what onMutateproperty-name does by simply connecting a watcher with the watch instance method...sans subclass override capability, and at the added expense of creating a watch handle and the rest.
On the other hand, connecting a watcher via a component's watch instance method is intended for use by clients of instances of the class. These connections typically should not result in mutating the instance state internally...if that was not true, then a particular instance would behave differently depending upon what clients had connected to its watch interface.
Of course, in JavaScript this is expensive to enforce and the library made the intentional decision to not construct enforcement machinery. This is a general principle of the library: encourage canonical design and implementation paradigms, but don't prevent the using engineer from doing what needs to be done (sometimes the world isn't perfect and we need to do what we need to do).

Is it possible to store instances of custom class in Vuex/(Vue data)?

According to vue documentation, it is not possible to store anything besides plain objects. (https://ru.vuejs.org/v2/api/#data). I always use vuex as a DI container, I see it from this point of view. It keeps vue away from my application business logic, and makes possible describe business rules only using JS with no dependencies. But that approach breaks vue dev tool, and for some reason not all tests pass.
Is there a way to circumvent this restriction? For example class instances can be created in getters rather than in mutations. But it does not work for me because some constructors of my classes have side effects (It's not a best practice, but that what i have).
You can absolutely store class instances in the store state.
I generally store arrays of models, which is really useful to keep logic in one place.
Something like:
Api.load('/api/users').then(res => commit('users', res.data.map(User.create)))

React props: Should I pass the object or its properties? Does it make much difference?

When passing props should I pass the entire object into the child components or should I individually create props first in the parent component and then pass those props to the child?
Pass entire object:
<InnerComponent object={object} />
Individually create props that're needed first:
<InnerComponent name={object.name} image={object.image} />
Which one is preferred and if it depends, what should I use as a gauge to use either?
According to the principle of least privilege, this is a correct way:
<InnerComponent name={object.name} image={object.image} />
This restricts InnerComponent from accidentally modifying original object or accessing properties that aren't intended for it.
Alternatively, properties could be picked from original object and passed as props:
<InnerComponent {...pick(object, 'name', 'image')} />
If there are numerous properties that are tedious to list, there may be single prop that accepts an object:
<InnerComponent object={pick(object, 'name', 'image')} />
You should prefer your second example, to pass the props individually.
There you can see explicitly which arguments are passed and can quickly compare with which arguments are expected. This makes collaboration along people much easier and makes the state of the application more clear.
I personally try to avoid passing whole objects if it's not needed.
It's like the spread operator where there can be any property inside and it is much harder to debug in a bigger scope.
Some additions to pure react like prop-types or typescript might help to define clear and expected properties in a big application
Since JavaScript has no type annotation, the second choice would be much preferable, as mentioned by #mstruebing the code will be more maintainable. However, if you are using TypeScript React (which support type annotation), both choice would be equally clear. But do keep in mind, the first choice promotes tight coupling between views and models, this allows fast development as you don't have to type much; while the second choice might slows down development but you have higher flexibility and tolerance to future changes.
So, the gauge is: if you favor development speed over flexibility, go for choice 1; if you favor flexibility over development speed, go for choice 2.
Extra notes
Ok, when should we favor development speed over flexibility? Here's my 2 cents.
If your project was meant for short-term usage (for example developing an app just for collecting votes during election), then go for the first choice.
If your project was meant for long-term usage (for example online bank transaction portal), you should go for the second choice.
Passing multiple props to a child component is the preferred way of passing props to child components. This will help you in tracking the state of the application in the child component.
Also, feel free to use the prop-types module. It acts like generics in Java and provides type safety for the props to pass in.
If you aren't making use of all the properties within the object, its better to pass the required properties separately as it can help in performance optimisation when the Child component is a PureComponent of use shouldComponentUpdate. In such a case, only when the props used by the Child component change, its will re-render and not when an unused property from within the object has changed.
However if your are making use of all the properties within the object, it doesn't make much of a difference event if you pass down the object as a props, provided you handle the mutations of the object correctly.
I agree with the other answers that in short, it depends, and the points raised in other answers are all valid.
Some other points I would like to add that also leans towards using individual properties are as follows -
Sometimes its not even the question of whether Do I need all the properties? It should be more of the question - Do I want to restrict the usage of the component to when I only have the complete object and not just a subset of properties.
Take for example a widget to display a car's image, make and model as part of a list of a widgets, its not reasonable to expect the full Car type to be available in order to display only the car's image, make and model. Only those 3 properties are required.
With the likes of rise of the likes of graphql where we can restrict the properties of data being returned about a type, we shouldn't always assume that components will have access to fully populated objects based on a type.
Lastly on the point of causing unnecessary rerenders of components down the tree, always passing the full object around, you are likely to cause all children that consumes that object will rerender when the object is updated. However passing separate properties to children, usually primitives, we can better mitigate against unnecessary rerenders
The whole point of objects is to encapsulate similar properties together. If you have about 10 properties and want to use them in your child component, stick with objects.
But in your case, my opinion is to use your second example as it makes the code in the child component simpler.
To the best of both worlds simply destructure those props that you need inside your child component.
Like this:
function InnerComponent({ name, image }) {
...
}
If you don't like braces in the arguments do this:
function InnerComponent(props) {
const { name, image } = props;
...
}
It depends on that Object. Do you need ALL of its properties to be passed to another component? Or... You might need to pass 2 properties out of 5 to a specific component?
If you don't need to pass ALL of its properties, I recommend passing
the Properties as Props
BUT, if you are 100% sure that you NEED ALL THE PROPERTIES to be
passed together, I recommend passing the whole Object as Props in
that case as it would be much clearer code and keeps you away from
forgotten to pass something. For example; When you add a new property
to that object, you don't have to pass it, as you are already passing
the whole Object!
Well, if you aren't certain about your current/future purpose of that Object as you might need to EXCLUDE some properties soon, you probably should pass its properties individually in that case, instead of passing some non-used properties to the other component.
You can pass props into JSX element as single object using React.createElement function.
Because each JSX element is just syntactic sugar for calling React.createElement.
The following 2 lines are equal for React:
<Button variant={"secondary"}>Add</Button>
{React.createElement(Button, {variant: "secondary", children: "Add"})}

Should I use a single Model object for the whole SPA or many small models for each component?

I am thinking about how to organize Model in my webapp. I have two options, as I see it:
Create a single globally available Model object, then on instantiating new components they must register themselves in the Model object via methods, then update it when their state changes. Others would listen to changes from the Model by some key.
Create a model object for each component and let others know via some Event dispatcher about their state change.
In 1st case I feel like it will be easier to manage all the state change in one place, have more standardized way of doing it, while with the latter scenario I think it will be harder to maintain consistence over the system.
What are the factors I should base the decision on?
I would go with the first but adding the idea of the second: Instead of the components checking constantly the keys for changes you can make the only model signal the components when needed after they register. You can pass the signal/callback with the register itself.
That way you don't need to create an army of models that update themselves (that might also mean you have to avoid cyclic propagation). In addition to this, if I understand correctly it would violate the single source of truth. Also it looks worse both memory and performance wise.

Does Angular $watch on an object include its prototype members?

I have created a tree structure in Javascript that, unfortunately, contains circular references. (Objects have an array of children, but the children need references to the parent for deletion purposes.)
Due to the tree structure, I'm using an angular deep watch to detect any changes to the tree. (This avoids watching every node of the tree.) However, the circular references cause problems with the Angular $watch construct. I don't see a way to deal with the parent/child issue without having references to the parents, due to some design requirements of my application.
One thing I've considered is storing the link to the parent as a prototype. My question - does Angular deep $watch look at the prototype members of a custom object? Is there a setting for this somewhere?
Thanks.
Another possible solution: The angular deep object compare ignores functions and fields starting with $.
http://docs.angularjs.org/api/angular.equals
So obviously angular uses $ to store its own metadata, but you should be good with something like obj.$my_parent. Or you could just assign everything with a function... obj.parent = function () { return other_obj; }

Categories