I am curious to know how angular js watches mutations which happens to a property added to $scope. From HTML point of view, I am able to get it, that we have some events which are fired whenever there's a change. But when it's regarding an object I am not able to understand how it actually works. I can see we have a function called Object.observe. But that is also deprecated as written here. And I am pretty much sure that angular does not use Object.observe. The doc of angular says that one can watch mutations using $watch and $watchCollection. But I am not able to get how these are notified. Can anyone help on this?
Angular will actually take a copy of the object being watched and compare against it every digest loop. So there are no notification when things change. It looks for changes every loop. And that's why watching can be expensive. The more watches you have, the more comparisons needs to be made, and in the case where changes are found, you might end up with a new run to make sure that the change that was detected doesn't affect one of the watched objects that you already checked.
I would suggest the book 'Build you own AngularJS' by Tero Parviainen. Even though it's not a 100% accurate source recreation, the concepts are the same, and you'll get good insight in how angular works.
Another source for understanding this part of angular is the chapter 'The Digest Loop and $apply' of the 'ng-book'. The concept is described there in a more 'accessible' form than in Teros book.
Related
The most confusing thing in this API is for me the reason why use it. I know ReactJS and RxJS and I'm used to the concept when view reacts to data change. So watching changes to DOM, which happens definitely after some mutations to data, I can't see much sense in it. So my question is when (not) use it?
You're thinking of the problem with a situation where you are already one step ahead. If you are using React/RxJS then the actual value of MutationObserver will most likely be very small.
Even within this, however, there is a clear possibility to leverage this. Suppose you are attempting to use a library within your React application that is not explicitly built for it, and modifies the DOM in some way, but want to extend this further or capture something from it. The best example for this would be augmenting FancyGrid further.
Currently, in a component, you would invoke such a library in componentDidMount, the same way the component above is built. However, this is simply fire-and-forget - you don't know when it is done executing, you don't even know what is happening on the "outside".
Enter MutationObserver. With it, before binding such a library to an element, you can use an observer to be notified of when elements are created, track them, and track property changes. The simplest use case for this would be to make a spinner above a (particularly time-consuming on load) grid.
In Angular 1.x we use to have digest cycle which triggers the watchers and update the view whenever there is a change in the binded property.
In Angular 2 we see that there is interpolation(one way binding) of properties in view when there is a change so how does this one way binding works under the hood.
Can someone please explain this?
Thanks
I found few pointers which suggested that there is something called Zone.js which helped getting away with digest cycle and $apply in angular 2.
Angular 1
When you write an expression ({{aModel}}), behind the scenes Angular sets up a watcher on the scope model, which in turn updates the view whenever the model changes
$scope.$watch('aModel', function(newValue, oldValue) {
//update the DOM with newValue
});
The second argument passed to $watch() is known as a listener function, and is called whenever the value of aModel changes. It is easy for us to grasp that when the value of aModel changes this listener is called, updating the expression in HTML.
$digest cycle is responsible for firing the watchers.The $digest cycle starts as a result of a call to $scope.$digest().
Angular doesn’t directly call $digest(). Instead, it calls $scope.$apply(), which in turn calls $rootScope.$digest(). As a result of this, a digest cycle starts at the $rootScope, and subsequently visits all the child scopes calling the watchers along the way.
for more detail plz visit : Angular Digist cycle
Angular 2
Basically application state change can be caused by three things
1.Events - click, submit, …
2.XHR - Fetching data from a remote server
3.Timers - setTimeout(), setInterval()
They are all asynchronous. Which brings us to the conclusion that, basically whenever some asynchronous operation has been performed, our application state might have changed. This is when someone needs to tell Angular to update the view.
Angular allows us to use native APIs directly. There are no interceptor methods we have to call so Angular gets notified to update the DOM.
Zones take care of all these things. In fact, Angular comes with its own zone called NgZone
The short version is, that somewhere in Angular’s source code, there’s this thing called ApplicationRef, which listens to NgZones onTurnDone event. Whenever this event is fired, it executes a tick() function which essentially performs change detection.
for more please visit : Angular 2 change detection
Basically, AngularJS was all about Two-way databinding, that ended up being very costly in terms of ressource usage with the $scope and the $watchers. You could always do One-way databinding, but that was not well made for that and it became hard to work with AngularJS.
With Angular2, since it's a different Framework, you can do both pretty easily.
Here is a good link that explains the different databindings possibilities :
http://tutlane.com/tutorial/angularjs/angularjs-data-bindings-one-way-two-way-with-examples
There are even more differences between those two Frameworks that you should learn about.
Here are some cool links that I discovered a few months ago that are quite helpful to understand why they went from AngularJS to Angular2 and contain all the answers you are looking for :
http://blog.mgechev.com/2015/04/06/angular2-first-impressions/
http://angularjs.blogspot.fr/2015/09/angular-2-survey-results.html
https://dzone.com/articles/typed-front-end-with-angular-2
Zone.js is something else :
https://github.com/angular/zone.js/
Have fun reading !
In the last week, I’ve been trying to make sense how two-way data binding (Angular) and one-way data flow (React/Flux) are different. They say that one-way data flow is more powerful and easier to understand and follow: it is deterministic and helps avoiding side-effects. In my newbie eyes though, they both look pretty much the same: the view listens to the model, and the model reacts on actions done to the view. Both claim that the model is the single source of truth.
Could anybody comprehensively explain in understandable way how they are really different and how one-way data flow is more beneficial and easier to reason about?
Angular's two-way data binding
It's made possible by a mechanism that synchronizes the view and the model whenever either change. In Angular, you update a variable and its change detection mechanism will take care of updating the view, and viceversa. What's the problem? You don't control the change detection mechanism. I found myself having to resort to ChangeDetectorRef.detectChanges or NgZone.run to force the view to update.
To not dive too deep into change detection in Angular, you trust it will update what you need when you change a variable, or when it gets changed after an observable resolves, but you'll find you have no idea how and when it runs, and sometimes it will not update your view after a variable changes. Needless to say, it can sometimes
be a pain to find where and when a problem occured.
React's one-way data flow
It means that the view always gets its state from the model. To update the view, you need to update the model first, and then redraw the view. React makes the view redrawing process extremely efficient because it compares not the actual DOM but a virtual DOM it keeps on memory. But how does change detection work in this dynamic? Well, you trigger it manually.
In React, you set the state's new value, which then causes a ReactDOM.render, which causes the DOM comparing/updating process. In React/Redux you dispatch actions which update the store (single source of truth) and then the rest. Point is, you always know when the stuff changes, and what caused the change. This makes problem solving quite straight forward. If your app depends on the state, you look at it before and after the action that triggered the change, and you make sure variables have the value they're supposed to.
Implementations aside
From a platform independent point of view, they're not so different. What separates one-way flow from two-way binding is a variable update on change. So your impression that that they're conceptually not too far from each other is not too divorced from their practical uses.
In Angular you have many controllers. One example would be a user triggering an action on View 1 that is managed by Controller 1. Controller 1 does something but also fires an event that is caught by another Controller 2. Controller 2 updates some property on the $scope and View 2 is suddenly changed.
Suddenly an operation on View 1, updated View 2. If we now throw in some Async callbacks and a bit more event chains, you might no longer know exactly when/how your views are being updated.
With Flux/Redux, you have a one way data flow. The view never updates the model, the views can only dispatch an action (intention to update), but lets the store/reducer deciding how to handle the update. You can more easily reason about the data flow because you can easily see which actions can be fired by each view. Then follow up to see how that action is being handled by the store and you can know exactly what can be updated.
Data flow here is a flow of write events - i.e. state updates
These events are flowing between views and controllers (and services, such as HTTP backends)
One-way flow is basically the giant cycle:
app view uses (reads, not writes) app state to render
when application gets some stimuli from outside (user typed some text in input field, or result of HTTP request has arrived), it emits write event - or, in Redux/Flux slang, dispatches an action
all events, from all controllers and views, are flowing into the single sink - dispatch function (reducer); although the nature of dispatch function allows it to be composed from simpler dispatch functions, conceptually, there's only one dispatcher for the whole app
dispatcher uses an event to figure out which part of the state is to be updated
go to start
Two-way flow aka data binding binds two pieces of state: in most cases, one inside the controller (e. g. some variable), and one inside the view (e. g. contents of textbox). Binding means that, when one piece changes, the other piece changes as well and gets the same value, so you can pretend that there's only one piece of state involved (while there's two actually). Write events are going back and forth between controllers and views - thus two-way.
Data-binding is cool when you need to figure out what variable holds the contents of this particular textbox - it shows immediately. But it requires complex framework to maintain the illusion of one piece of state where there's two pieces really. Usually you'll be forced to use framework-specific syntax to write your views' code - i. e. to learn yet another language.
One-way data flow is cool when you can leverage that extra entity - events flow. And, usually, you can - it's useful for Undo/Redo, user actions replay (e. g. for debug), replication, etc, etc. And the code to support this is much, much simpler, and usually can be written in plain JavaScript instead of framework-specific syntax. On the other hand, since you no longer have data-binding, it no longer saves you some boilerplate.
Also, see great visual explanation in this answer: https://stackoverflow.com/a/37566693/1643115. Single-headed and two-headed arrows visually represents one-way and two-way data flow respectively.
Let's say your app is just a wizard flow, but it has some complex interactions i.e. one step might change a following step behavior.
Your app is running great, but one day an user reports a bug on one of the tricky steps.
How does debugging would work on two-way binding and one-way binding?
Two-way binding
I'd start checking what behavior is different and with some luck, get to the same point as the user and pinpoint the bug. But at the same time there might be some weird interaction between different parts of the app. I might have some data-binding that is incorrect (e.g. replicating the model state but not binding) or other weird intricacy between components that is hard to debug. It might be hard to isolate the bug.
One-way binding
You just grab the state object. It has all the information of the app currently in a big javascript object. You load the same state in your development environment, there is a big chance your app will behave exactly the same. You can even write a test with the given state for regression and pinpoint the exact problem that is happening.
Conclusion
In a few words, one-way binding makes it very easy to debug complex apps. You don't have to do much then copy over the current state of the user.
Even that doesn't work, you can log the actions as well. There isn't AFAIR an easy way to track all the state modifying actions on Angular, for instance. With Redux it's pretty, pretty easy.
I know a lot of the big name MVC, M** style JavaScript frameworks allow 2-way binding with Observables.
Meaning if I:
Update a DOM input filed, it will also update a JavaScript object variable which could also save to server with AJAX request.
If I update the JavaScript object variable, it will also in turn update the DOM text field.
As I am learning JavaScript, I would love to skip the big name libraries and learn how to do this in it's most basic raw JavaSript form.
Can anyone provide quick easy to understand demo of this functionality without using libraries like BackboneJS, Knockout, Angular, or others?
jQuery is acceptable.
I would appreciate the lesson and help please.
This is different in every framework.
Angular for instance saves every variable on scopes. Iterate through the scopes variables and compare the values with the previous ones and if there is a change it is carried out to the DOM.
This check is made upon they call digest cycles. If one cycle is finished it calls again until every variable 'observed' is the same as it was in the previous cycle. You can also add objects or vars to this 'observer'.
Angular keeping the view current, with calling this digest every time something could change the 'observed' vars, like http calls, user interactions ... but for instance, if you change a variable outside from angular (console), than the variable change is not carried out to the DOM. You have to call a digest cycle manually to do so.
In HTML5 it is a bit easier with Object.observe, but it is not yet supported in every browser currently on the market.
Hope I could help
I was reading some article to understand a little bit more how AngularJS works.
One of the terms that I didn't understand is Dirty Checking.
What is it exactly? It seems like the Observer pattern but apparently it's better.
Can you help me understand this please?
EDIT : it can be also useful for people who wants to learn more about that to watch this video from swiip at NgEurope some years ago.
From this link:
Angular defines a concept of a so called digest
cycle. This cycle can be considered as a loop, during which Angular
checks if there are any changes to all the variables watched by all
the $scopes. So if you have $scope.myVar defined in your controller
and this variable was marked for being watched, then you are
explicitly telling Angular to monitor the changes on myVar in each
iteration of the loop.
This "digest" is also called "dirty checking", because, in a way, it scans the scope for changes. I cannot say if it's for better or for worse than observable pattern. It depends on your needs.
Some links:
Angular documentation
A blog post about Angular scopes
Angular Dirty Checking mechanism workflow.
Dirty checking is a simple process that boils down to a very basic
concept: It checks whether a value has changed that hasn’t yet been
synchronized across the app.
Our Angular app keeps track of the values of the current watches.
Angular walks down the
$watch list, and, if the updated value has not changed from the old
value, it continues down the list. If the value has changed, the app
records the new value and continues down the $watch list.
Check out the whole article here
What is dirty checking?
The process of checking every watch to detect the changes, is called dirty checking. There could be two scenarios
First –
Get a watch from list
Check whether item has been changed
If there is no change in item then
No Action taken, move to next item in watch list
Second–
Get a watch from list
Check whether item has been changed
If there is Change in an item
DOM needs to be updated, return to digest loop
In second case, loop continues till it finds no changes in the entire loop. And once it completes, DOM gets updated if required.
Just modifying a previous answer...
Angular has a concept of ‘digest cycle’. You can consider it as a loop. In which Angular checks if there are any changes to all the variables watched by all the $scopes (internally $watch() and $apply() functions are getting bonded with each variable defined under $scope).
So if you have $scope.myVar defined in your controller (that means this variable myVar was marked for being watched) then you are explicitly telling Angular to monitor the changes on myVar in each iteration of the loop. So when the value of myVar changes, every time $watch() notices and execute $apply() to apply the changes in DOM.
This "Digest" is also called "dirty checking", because, in a way, it scans the scope for changes. As all watched variable are in a single loop (digest cycle), any value change of any variable forces to reassign values of other watched variables in DOM.
PROS: This is the way Angular achieves Two-way data binding.
CONS: If there are more watched variables in a single page (>2000–3000), you may see lag while page loading. (But I say if there are that many ‘watched variables’ in a single page, it is a bad page design :p).
There are other cons, as well as are workarounds also :D
Dirty checking
will check anything changes in $scope variable and update it to the DOM.
This done by angular js, you can also implement dirty checking by your own.
I read a great article about dirty checking in this blog post. There was also this SO answer
TLDR; version
When the $digest cycle kicks in, the watchers will check for any changes in the scope model and if there are any (the change might also come from out-of-Angular-domain), the corresponding listener functions are executed. This will again run the $digest loop and checks if the scope model was changed (the listener function could also modify the scope model).
Overall, the $digest cycle will run twice even if the listener does not change the model or till it hits the max loop count of 10.