 So, the workshop is on attempting to create a mini framework like Angular. Is that what it is? Yes? Right? So, the reason why I prefixed attempting is that after proposing this topic then I realized what foolishness I made me, made me give this topic. Now it is not because of the complexity that is involved, it is because of the time constraints within which we have to achieve this. Right? So, what we will try to do is as much as possible, we will try to cover the base and then leave you with the details wherein you can proceed from there. Is that clear? Right? So, if we try to replicate something that has been done over 2 years in 2 hours, obviously it is going to be a lot of challenges. So, let us lay the foundation a little strong so that in case if you attempt to, I will share the code. So, in case if you attempt to go through it, it makes things clear. So, that is what is going to be my goal today. Okay. How many of you attended the previous conference? At least my presentation, previous presentation. Thank you. I thought the presentation was good. It is possible. Very much possible. Good. Let us look at this. I am assuming that everyone is already using Angular, at least familiar with Angular, right? Is there anyone who is not, raise your hand. Who is not used to Angular? Not used to Angular? Not used to Angular? Oh, okay. Good. Good. Okay. So, we will have to cover a little more base before we proceed any further. I will make sure that I will keep things interesting as much as possible. For people who used Angular or who still use Angular, what do you think is the nucleus of Angular? If that is not there, Angular is not there. What is that one aspect that you think is the nucleus of Angular? Data binding. Data binding. Routes. Dependency injection. Services. Routing. Routing? Who said that? Scope. Who said scope? Excellent. Right? I share your opinion as well. This is personal opinion, so there is no right or wrong answer, no gifts. So, I share your opinion as well. So, what is the role of scope? What is the role of scope? If you ask me, right, everything in Angular revolves around scope. There are very few things that stay away from scope, but everything in Angular revolves around scope. Scope is what binds everything together, right? Scope is what binds everything together. What is the problem that scope attempts to solve? Absolutely not. Separation of concerns. Right? Separation of concerns. Scope attempts to ensure scope attempts to help you in keeping proper separation of concern between the model and the view, right? Scope helps you. And if scope stopped there, Angular would have been one another framework. If it had stopped there, Angular would have been one another framework, a simple framework. It wouldn't have been a framework, but it would have been a library, right? Now, the beauty about scope object is, of course, the core problem is to help you separate, keep model and view separation, right? Maintained across the application. It does it in such a fascinating way that there are a lot of concerns that are by default taken care by Angular for you. There are a lot of concerns that are by default taken care by Angular for you. Now, in order to understand this, right, in order to understand this, what we will do is we will try to solve a problem without Angular and then try to mimic what Angular does there. Am I making sense? Right? We will try to solve a problem without Angular. Of course, this problem has the way we solve the problem is going to be completely different from Angular because if we have to solve it the same way Angular does it, then it would take a lot of time. So we will solve it in simple ways. Our goal will be to get it done, right? Make it make a workable functioning product, right? Make a functioning product and then we will see what are the pros and cons of that particular approach and how Angular attempts to solve this particular problem. Okay. Now, bad with me for people who have already attended my presentation, I am going to use the same example, okay? So bad with me, I am going to use the same example because I find that it is very simple it appeals to or it serves the purpose, right? So pretty much that is what I am going to do. So just bad with me. And by the way, I don't use any presentations, any PPTs. So bad with me for that as well, all right? So let me create a presentation index.html, all right? So let me create a plain simple html page, right? I will expand this, but I will also share this in GitHub in case if anyone of you is interested. Give me a couple of minutes, all right? So now we have a very basic simple html available. Let me try to make it a little presentable. Just give me a second, field, margin bottom is 10 pixels, do we need 10 pixels, 5 pixels we'll do and then label, sorry, display is block, font size is red color, okay, good. So we have a very, very basic html page. We have a very basic html page. And a very simple problem in salary, actually four components, you have basic HRADA tax and people who are not from India, I'm so sorry if this doesn't make sense, right? So this is purely our Indian salary components, right? So all we have to do is what? The user should be able to enter the data and he should be able to, right? So don't be amazed people from not from India because these are all in rupees, not in dollars. And you use the range for selecting the salary, I mean tax and then you click calculate and the user gets to see the result, very basic problem, very, very simple problem. Now I'm going to solve this problem directly using jQuery, right? I'm going to solve this problem directly using jQuery. So let me have jQuery brought in here. And so if we solve this problem in jQuery, typically what we will do, we will say dollar off a function and dollar off hash button calculates dot click is where we would go about writing the code function, come on. This is the challenge with live coding, okay? So our basic is equal to percent of, still I didn't do it wrong, I did write, okay? So hash text basic dot val, yeah, comma 10. So just take this and try to, okay, good. This is hra, da, this is text hra, text da, and range tax, okay, good. Now guys who attended the last year's presentation, don't worry, this is where the similarity ends, where gross is equal to basic plus hra plus da and where net is equal to gross multiplied by 100 minus tax divided by 100, okay? So dollar off hash give results at html of net, got it, all right. Now range tax dot change, we just need to do something and tax dot html of this dot value, done, right? Now this will more or less bring live to the, did I, okay, good, there are no errors. So 10,000, 2000, 3000, yep, right, it works, most likely it works, it works perfectly fine. Now unfortunately what we have done, we have solved the problem, of course for this scope this is more than sufficient, if the application is a throwaway application, this is more than sufficient, you just have a functioning application and it serves the purpose for that moment, right, it serves the purpose for that moment. But if you are building a slightly complex application and you want to manage it for a long period of time, if you have, the shelf life of the application is longer, right, which is almost all applications, which is almost all applications. So how many of you have had experiences where you built something as prototype and you saw it being used for the next 10, 15 years, I did, right? So I am actually hiding away from the guy who is maintaining it today, because if he sees me, he will kill me, right? So when you build a simple throwaway applications, just solving the problem is more than sufficient, but the moment you want to manage it, the moment you want to make it maintainable, easy to change in future, then definitely the most important thing that you need to do is identify components that share distinct responsibilities and make those components communicate to each other, right? So that is where a good developer's job comes into picture, right? Now, what is the problem with this approach? The problem with this approach is we have written everything inside DOM manipulation code. So tomorrow if I have to change the logic for, I'm sorry, if I want to change how the salary is being calculated, right? I need to look for the button click method. There is no one who is responsible in calculating this. We would typically like to do is we would create a class, function, salary calculator, right? And initialize it with some defaults. So this dot basic equal to zero. This dot hra equal to zero. This dot usually I do it in one line, but in the tax equal to zero. And this dot salary is equal to zero. And salary calculator dot prototype dot calculate is equal to a function. And where gross is equal to this dot basic plus this dot hra plus this dot da. And where net is equal to gross multiplied by 100 minus this dot tax divided by 100. And this dot salary is equal to net. Good. Now we have a calculator class that takes that representing a calculator. That represents a calculator with all the attributes. So the state of the application is represented in this particular class or to be more specific, the object created out of this particular class. And now what we are supposed to do, because the state and behavior, especially the domain behavior is being delegated to the responsibility of this class, what you are supposed to do? You are supposed to extract that information from here. It is not going to be here. No, this is bad. So how will I do that? Typically you do it by saying where calculator is equal to new salary calculator, okay, create an instance of the model. And you don't do this all by yourself. You give it to me, I will take care of it, right? So this has to be given to the calculator. This has to be given to the calculator. And once you give this, just ask the calculator to calculate. Just ask the calculator to calculate and then just take the calculator dot salary. Make sense? Now, will it make any difference in the behavior of the application? Absolutely not, right? Will it make any difference in the behavior of the application? Absolutely not, but it will help you increase your lifetime. In case if you happen to meet someone who manages this, right? So now, we have the model and the interaction part completely separated. No challenge at all, very simple. Then, what is the problem with this approach? What is the problem here? Is this fine? Is this fine? This is perfectly fine except one particular aspect, what is it? Exactly, right? So the view drives the application. If you look at it, what is happening here? The view drives the application. It is not the model that drives the application. It is the view that drives the application. So when the data has to be populated is determined by the button. When the data has to be shown to the user is determined by the button, right? So those things where, so what if tomorrow? What if tomorrow? Something else results in change of the salary. Tomorrow something else results in change of the salary. How are you going to deal with that particular scenario? In this particular scenario, what you have, in this particular case, what you have is we have written our code in such a way that only the button click will result in change of salary. So we receive the data and we display it here. We receive the data and we display it here. But what if something else in future, something else, some other action in the application results in change of salary? Will your application interface show that properly? No, right? So you will have to modify that as well. So what is the solution? The solution is very simple. Don't drive the application through your view. Don't drive your application through the view. The model is the one that has to drive. Which model, any model you decide. You name it as view model, domain model, I don't care. But the model has to drive your application. The view has to be responsible only for acting as an interface, but the model has to drive the application logic. Now in order for you to drive the application logic through the model and make sure that the view doesn't act anything on its own, right? So primarily what we try to do here is, if you look at here, the view has too much knowledge about the model. Yes or no? Right? You see, you take this case. Can I take this and move it up? Will this work? Now, when you look at the calculate method alone, does it reveal that it has a dependency on basic HRA, DA and TAX? Then why did we write this sequence? Because we have knowledge. You understand? This is the knowledge that we are talking about. The knowledge in the view did not be always in terms of complex business logic. It need not be always in terms of a large for loop, a switch case statement. No, it need not be. It can be as simple as the sequence in which you perform your actions. Even that can reveal knowledge about the model in the view, which we have to avoid at any cost. If you don't avoid it, then you are in trouble. So what am I supposed to do? If this has to go away, right? If you look at here, the view is trying to be proactive. You agree with me, right? Because of the knowledge it had on the calculator, it is trying to be proactive. It says, oh, okay. Now, since I know very well that internally the calculator method depends on basic HRA, DA and TAX, I need to make sure that these are populated before. I call the calculate method. Before the calculate method is called. The view is being proactive. And if you want to build maintainable applications, the view should not be proactive. What is opposite of proactive? Reactive. What is opposite of proactive? Reactive. When can you be proactive? You can be proactive only when you have knowledge. By forcing the view to be reactive, you are making it dumb. Is that clear? Right? By forcing the view to be reactive, you can automatically push it to be dumb so that it doesn't act. It doesn't do anything on its own. It's still, it just reacts to two things. What are the two things that it will react? It will react to user actions, and it will react to, it will react to user actions, and it will react to model changes. These are all the only two things that it is expected to do. It is not expected to do anything on its own, right? It is not expected to do anything on its own. Okay, very good. This is where the frameworks and libraries comes into picture. We want the model and the view to communicate to each other, but in this process, we want the views to be completely reactive in nature. We want the views to be completely reactive in nature, and this is where the libraries comes into picture. The library says, okay, now you don't have to worry about these things. You bind this with this, I will take care of making it reactive, right? Now, when you look at, when you look at most of the libraries, you will find that in order to accomplish this, you will make the models emit events which the view will subscribe to. Yes or no? Right? You will find that the models emit events because unless the model says that it has changed, unless the model says that it has changed, the view will not be able to react to it. The view will not be able to react to it. So in our case, right? I see a lot of puzzled faces. Let me quickly implement this part, and then I'll come to that. Now, look at this part. This is what is the knowledge that I'm talking about, calculated or calculate. So which means that whenever the calculate method is called, the view knows that the salary is undergoing changes, so it is updating it. What is this? This is being proactive. This is being proactive because the view knows that the salary changes. So as and when it calls the calculate method, you have also written the code to update the salary in the UI. This is being proactive. But if I have to convert this to be reactive, what am I supposed to do? How do I go about with this? The model will say that the salary has changed, and to this, the view will react. The model will say that the salary has changed, and the view will react. Now, if I have to do this, if I have to implement this, let me go for a very, very crude implementation, and you have to forgive me for doing this, but still. So I'll simply say on salary change, very simple callback, null. And here you set this, and then say this dot on salary change equal to, oh, sorry, if this dot on salary change is equal to a function, type of, if type of, right? You can do a type of, you can just do a check, whatever it is. So you can simply say this dot on salary change. You are invoking it. Now, if this is not to be done, then how else this can be done? Very simple. You have created the calculator, and tell the calculator, hey, whenever you tell me that the salary has changed, please execute this, please execute this code, right? Now the communication happens in reverse direction. They, you trigger the calculate method, and the view intern calls the model, I'm sorry, the model intern calls the view and says that the salary is changed, right? And it lets the view react to it. It lets the view react to it. Now, this is, in this case, right? In this case, all you have is just one view, one model. When you build a complex applications, you will have one model being bound to more than one view. You will have one model being bound to more than one view, right? If we have to talk about rich internet applications, what is the one application that you will say? This is my reference. This is how an application has to be built. Which application you will say? Facebook? Okay, anyone else? Okay, anyone else? Exactly, right? Gmail is the foremost application that brought in the whole idea of rich internet application to the world, right? It is one of the best applications. When it comes to the presentation aspect of it, it may not be that fancy, but when it comes to the behavior aspect of it, it is brilliant, right? And these things were there even when we, at least I did not know about rich internet applications. So I am going to trust you guys and open my Gmail. Give me a second. Oops, okay, I need internet access. I'm sorry. I forgot. Give me one second, guys, sorry. Come on, come on, come on, come on. All right, all right. Okay, I'm back, sorry, right? So now, so when you take, when you look at Gmail, when you look at Gmail, I don't know if I, if you remember this example. So let me open one of the mails. And as a matter of fact, let me delete this guy. So I'm opening one of the mails. And what I can do is I can open the mail in the same, in multiple windows, right? So I'm opening the same mail in multiple windows. So now this is one window. And this is another window. So the same mail is being opened in multiple windows. And, right? Now, when you perform an action on this particular mail, you'll find that Gmail instantly makes sure that that particular state is reflected everywhere. So you try to make it as 100 here. Mark as 100. Watch a, I mean, have a careful eye on this particular row. What you see in the background. So the moment you say mark as 100, you see that, right? It has struggled to become 100. Now, look at this, the, the, the, the important indicator. Now, if I make the mail important here, in this particular window, you'll find that it is reflecting here and as well as here. Unimportant, it reflects here and as well as here. Every action that you perform, every action that you perform on the mail, irrespective of how many views the mail, that particular model is being shown, all will make sure that they reflect the current state of the mail at all times. They reflect the current state of the mail at all times. Now, does it mean that one view is talking to another view and say, hey, I have changed. Can you please, right? That can, that can, that, of course. I mean, we have built applications that did that. But then we learn from our mistakes, right? Or at least we help others learn from our mistakes. So, when, when this happens, when this happens, typically what, what do you need? You need a way by which your, your model can be subscribed to all the changes and it can let others know whenever it is undergoing changes, right? Now this infrastructure, who, where, where is this infrastructure? In order to build this infrastructure, what we have done, I'm sorry, what we have done, we have assumed that there is only one view, right? This is one view and this is one model. And we, we received only one handler. We are capable of receiving only one handler so that we can call and inform only one person, one, one subscriber. But what if there are multiple views, like whatever we just saw in Gmail? What if there are multiple views who also want to know what is happening here? Now, our model's infrastructure has to be enhanced. Our model's infrastructure has to be enhanced. So, I should, that should be a way by which I receive multiple subscribers and I need to figure out the appropriate times when these subscribers are invoked, when these subscribers are invoked. Are you with me? Right? Now, okay, a slight deviation from this. What challenges you will face in case if you have this infrastructure? If you build this infrastructure of your own, what are the challenges? Have you built one of your own? Anyone? If you attempt to build one of your own, right? There are some very, very interesting challenges. Like, say, for example, so in this case, in this case, let me try to increase the scope of this. So, I'll say, because I want to access it through the console, so I'll say window.calculator equal to salary calculator and I'll say this dot on salary change is an array, okay? And then, here, I am simply going to go through that particular array and invoke it. So far, where I equal to this dot on salary change, dot for each, take one callback at a time and then simply invoke the callback. Now, the caller, right? In this case, I am exposing this array directly, but actually what you have to do? You have to simply have an accessor method through which you will do it. So this will be dot push, this function, okay? Very good. We are done with this. Let us verify if this works. Gmail, your job is done, okay? Now, let's go back, make sure that this works and nothing. Okay, good. There are no errors. It works perfectly fine. Now, what I can do? Let's assume that the console is another view, right? The console is another view. Now, as of now, this will work perfectly fine. As of now, this will work perfectly. This will work perfectly fine. Now, let's assume that the console is another view and there are two more subscriptions that we add to the on salary change. So we'll say calculator, dot on salary change, dot push, right, one function. So this is one subscriber. This subscriber is definitely not under the control of the model. Does the model has any control over the subscriber? No, so what this guy does is he simply says through new error, very intentional error. And then there is one, another very genuine subscriber who also want to know when the salary is changed. Console.log, right. Now, when you try to calculate the salary, does the third subscriber receive the notification? So if you have a chain of subscribers, if one is a rogue subscriber, he can stop the notification being going to, how do you solve this problem? Huh? Tri-catch will not help. Where will you do a tri-catch? So basically here, right? Okay, so when I do a tri-catch, do I know how to handle this error? So when you don't know how to handle this error, you are not supposed to catch it. Is there no, you are eligible to catch it only if you know how to handle it. You are not supposed to catch it if you are going to gobble it, no. So I can't have a tri-catch here. What is the solution? The solution is, don't call it in the same call stack. Don't call it in the same call stack. Delegate it to the responsibility of the browser event loop to invoke it. How? Set timeout. So simply say, set timeout of this function, right? Now this will take care of that. So let us do this on salary change, every intentional error, rake-console.log. Now you do this, calculate, you'll find that this is happening and the error is thrown, of course the error is thrown, but at least the model, the subsequent subscribers are still receiving the callback. If it throws an error, that's not my problem. My responsibility ends letting you know, right? My responsibility ends letting you know. So even building a very, very simple subscriber, publisher subscriber implementation has quite a few challenges. And this is where the libraries attempt to solve this problem. This is where the libraries attempt to solve the problem. Okay, good. Now, as someone rightly said, right? What does the scope do? In AngularJS, what does the scope do? So what is scope? Let us look at that first. What is scope? Scope is basically just an object, that's all. It is just an object. It is just an object. And what it offers? What is the value addition that it brings to the table? What is the value addition it brings to the table? So if you look at the way we have implemented it, we have the model, we have the view and they have to communicate to each other. The model and view have to directly communicate to each other. So this brings in a few challenges. What is it? Your models cannot be plain simple JavaScript objects. They have to be enhanced, right? They have to have eventing infrastructure built in. Publishers, they have to behave like publishers. They can't be just plain simple models. They have to behave like publishers. And not everyone need to be a publisher, but if you want to build an application that has, say, 50 models, every model has to behave like a publisher. Every model has to behave like a publisher so that it keeps emitting events to the views so that they get to know whenever it is undergoing changes. This is one major challenge. This is one major challenge. And it is on this premises backbone is built, if you look at it, right? So when you create a backbone model, what do you do? You say you are model equal to backbone.model.extend. So you are not writing the infrastructure, but still you inherit that infrastructure. You don't create it, but still you inherit that infrastructure from an abstract base class, right? Called as backbone.model. Now, even though that helps, right? Angular attempts to solve this problem in a simple way. What does Angular do? Angular says, hey, you know what? You don't have to worry about your models emitting events. Don't worry at all. Just give me your model. Just give me your model. You make changes. Whenever you want to make changes to the model, you keep making changes to it. And whoever wants to know when the model is changing, I will take care of letting them know, right? I will take care of letting them know. So Angular stands between your model and the view taking care of this, I'm sorry, scope stands between the model and the view taking care of the responsibility of letting the view know whenever the model is changing. Here I'm using the term view, but it need not be. It can be anyone. Any entity that is responsible or that is interested in getting to know when the model is changing, right? Any entity that is responsible for interesting to know when the model is changing, okay? Now, how does the object offers this functionality? How does the object offers this functionality? So basically, it's an object, right? It's an object. What it tells you is, first and foremost, you give me the object. Whatever you want me to track, whatever you think that need to be notified to the other entities when it is changing, give it to me, right? Give it to me. So you say scope dot whatever. In this case, it is calculator, right? Equal to whatever is your object. So in our case, I'll simply say new salary calculator. Just create it and give it to me. Are you with me? Give it to me. Okay, very good. Fine, I have given it. Now, I have already told the views that, hey, you know what? I am not responsible to letting you know whenever I am changing. Don't talk to me. Don't come to me. I don't know how to talk to you. I won't let you know. I don't have the infrastructure anymore. Then who has it? Scope has it, okay? Now, how will I tell scope? Hey, let me know whenever the model is undergoing changes. How will I tell the scope? Hey, let me know whenever the model is undergoing changes. So from the views point of perspective, from the views point of perspective, the scope exposes one method called dollar watch. The scope exposes just one method called as dollar watch. So to the dollar watch, you can pass an expression. You can say, hey, what I want to listen to. So in this case, it is a calculator. Maybe I'll say, please let me know when the basic is changing. And then you pass a callback function. And then you pass a callback function. Now, since the scope takes care of letting the views know whenever the model is undergoing changes, the model can be completely free from this responsibility, right? And the function that you have passed, what is called as a watcher function, the function that you have passed will be automatically triggered whenever the calculator's basic is changed, whenever the calculator's basic is changed, except that there is one disclaimer, conditions apply, a small asterisk. The condition supply is this. Because you are depending on the scope to let the view know whenever it is undergoing changes, you need to take one more burden on your shoulders. What is it? You have to make changes to the model only with the knowledge of the scope. Does it make sense? Make changes to the model only with the knowledge of the scope. Now, you don't have to explicitly say what has changed. That scope will take care. You don't have to say, hey, basic changed, no, you don't have to do that. If the model has to do it, then scope has no value here. Yes or no? The scope doesn't bring any value addition here. So you don't have to explicitly say, you just need to say to the scope, hey, I am going to make changes to the model. I am simply going to make changes to the model. Whenever you are making changes, just do it with the knowledge of the scope. So how do you do that? Very simple. What you do is, so this is from the views point of perspective. And from the models point of perspective, you say whatever changes, whenever you want to modify the model, do it from inside your function that is being passed as argument to the dollar apply. The way you have the dollar watch function, you also have a dollar apply method and that takes a function as an argument. So whatever changes that you want to make to the model, do it here. So that scope becomes aware of it and then it can let the entities know whenever it is undergoing changes. That's it, very, very simple. At the, at the, what to say? At the core, at the very core of scope, this is what it is. At the very core of scope, this is what it is. But a lot of other things are built on top of this. A lot of other things are built on top of this. Are you with me? Is that clear? Okay, good. Now, the difficulty or not, I won't call it as a difficulty. Things that are a little unclear at this point of time is how will I get the scope? How will I get the scope? So I'm going to write a two line code. I'm just going to write two lines of code that will give me access to the scope object from Angular, right? It is not straightforward. That will give me access to the scope object. So don't worry about it. I'll take it through it a bit later. But for now, treat that as a black box. You don't know what's happening, right? You ask it, it is going to give you. So let us solve the problem using Angular. Let us solve the same problem using Angular. So let me bring in AngularJS. Bring in AngularJS and let's go here and script colon source. Script colon source, Angular. Okay, very good. Now, how am I going to get the scope object? Very simple. I'm simply going to say angular.bootstrap of document.element, an empty array. There are several ways by which you can do it. I'm taking the simplest way, okay? So angular.bootstrap, document.element, and this gives you a module. And I can get the scope object by simply saying scope equal to angular.element of document. What did they do? Sorry, bootstrap of document.body, and then where scope is equal to angular.element of document.body, can you please give me the scope associated with document.body? Can you please give me the scope associated with document.body? Now you have got a object. Now you have got a, yes sir, I'm sorry, we will, we will, give me some time. We will, there are at least half of them who has not used Angular. Give me some time, right? So we have got the scope object in place. Now I told you that the scope object exposes two methods. What are they? Apply and watch. So let us look at that. So scope.dollarapply is one function and scope.dollarwatch is another function. Are you with me? So this is what we will be using. So how will I use this? So let us quickly use this to solve this problem. So window.calculator, okay, that's fine. In fact, as a matter of fact, even before this, I'll say angular.bootstrap. of document.element, and empty array. And then where scope, I'm sorry, thank you. Thank you. Am I doing that again and again and again? Body. And let us try to get the scope object assigned to the window. Window.scope equal to angular.element of document.body.scope. This will get us the scope. And here, I'll say window.calculator equal to, what did I say? I said that when you create the model instance, give it to the scope. Scope will take care of it. So I'll say scope.calculator is equal to window.calculator. So window.calculator and scope.calculator both are the same references. I'm maintaining two different references. That's all, nothing else, right? Because I don't have to change everywhere. So I'm maintaining just two different references. Now, let me delete this. I'm not interested in this anymore. I'll come back to this a bit later. Let us see how this works. Now, if you look at how this works, I'll take this scope object and then say, dollar watch of, what is that I want to watch for? I want to watch for the basic, whenever the basic is changed, and you simply say console.log basic changed. Console.log basic changed. Very good. Now, let us take the calculator and say basic equal to 10,000. What happened? Function is not called. I told you, conditions apply. What is a condition? Any changes that you are making, make it inside dollar apply. So let us say scope.dollarapply past the function and do it inside this particular function. So make it to 2000. It says basic changed. It says basic changed. Very simple infrastructure. Very, very simple infrastructure. Now, if I use this to solve this problem, if I use this to solve this problem, it's going to be something like this. Now, I don't do this here. I will not do this here. I don't do any of this. My model will remain plain simple JavaScript object, whereas if you look at the way I solve the problem using, in the view, it'll be something like this. Dollar of hash takes to basic.change. Whenever it is changing, do something. What is it? Where self equal to this and then say scope.dollarapply of a function and inside the function, say calculator.basic is equal to self.value. Calculator.basic equal to self.value. So whenever the text box is changing, I am updating the calculator object, but I have to update it inside the dollar apply. And because this function is going to be not called by me in the sense like the text box, when this is called that this context will be different. So that is why what we are doing, we are taking a closure on this self, I mean on this and then use that inside our callback. Scope.calculator, you can do it using window.calculator. I already have the reference here, little help. Thank you. And this is one way. So whenever the text box is changing, you are updating the model. Whenever the text box is changing, you are updating the model. But the reverse direction, whenever the model is changing, the text box also has to change. So we will say scope.dollar watch of what? Calculator.basic comma a function. And this is invoked with the new value comma old value. And here all I have to do is dollar off hash text basic dot val of the new value. Pretty much that's it. Pretty much that's it. So now let's go back here, reload it. Now when you enter some data in the text box, come back here and look at calculator, it's basic is updated. Now it is in string format. Did you notice? We are not converting it, right? I'm retaining as it is. So this is in string format. So my calculate method has to undergo changes a little bit. Why? Because I will have everything in string format. So these have to undergo changes. So let me quickly create a helper method that will make my job a little easier here. Object.prototype.toint is equal to a function. And we'll say return percent of this comma 10. Because I'm attaching it to object.prototype, what I can do, wherever I am performing the calculation, I will simply need to don't take it on the value that is given as it is converted into a number. This will work for both numbers and as well as strings. Of course, I'm not handling any errors here. Now this we will have to repeat it for each of them. This we will have to repeat it for each of them. So here is your text basic and this will be your text HRA and this will become HRA. And this is text DA and this becomes DA. And this is basic HRA DA. All right, now just give me one second. Let me validate this HRA DA and range tags, button calculate. So in the button calculate, I don't need to perform any of these operations. I don't need to perform any of these operations. All I have to do is what? Scope.$apply, pass a function and inside this perform this action. Make sense, right? And apart from this, I also need to do one more thing. What is it? I need to subscribe to the tags and display span tags.html. And the same thing need to go in for salary. Whenever the salary is changing, display hash div result. Now I don't need these things as well. I think we are good now. So save this, go back, reload this. Now just keep entering, you see that now? So it has changed and button click, calculator.calculate, calculate.salary, scoped.$apply, hash div result, value is new value. Ah, thanks, thanks, thank you. Wrong, right? Is it? No, 6% tax, 8000 minus 6. Why? Why somewhere we are missing range tags, calculator.calculator.tags, range tags, value takes DA, value, basic, okay. I think we are good now. Now, if you look at here, what we have done is, we have simply said, hey, pair of functions or functionalities, one takes care of one direction, communication in one direction. When the control is changing, it lets the model know about it and the other is communication in the other direction. So whenever the basic is changing, this guy reacts to it. So if I have to demonstrate this in here, let us do this. So we still have the calculator reference here. I'll say basic equal to 10,000. Let's assume that this is another view, right? And then we'll say scope.dollarapply of a function. And here I am performing this action. Now, you see the text box, right? The text box is updating. So here you consider the console as the mail opened in another window, the mail opened in another window. So all, when you look at the way the model has been returned, right? Of course, we wrote a lot of code in the view part. We wrote a lot of code in the view part. But how the model is returned, if you look at the way model is returned, the model does not need to worry about any eventing infrastructure, publisher, subscriber, nothing. It can be a plain simple JavaScript object. It can be a plain simple JavaScript object. Am I making sense? Right? So guys, this time is spent on people who have, who said they have not worked in Angular. Is it clear? Any questions? Very good. Now, yeah. When I am in the scope. At least at this point of time, that is how I have written. At least at this point of time, that is how I have written, right? But there are ways and means by which you can optimize it. There are ways and means by which you can optimize it, right? But typically this is what you are doing. This is what you are doing. Have you ever wondered how, when you press a character in the text box, one of the most popular examples in Angular is what? You have a text box and you have a deal. You type something in the text box, it immediately appear in the, this is what is happening. You are actually triggering that, right? But it happens so fast that you don't see a delay. Right? Okay. Now, if you look at this, if you look at this, right? This code is pretty much the same. I actually copied and pasted this code. You agree with me? I actually copied and pasted. There are, and modified a few things. Is there a way by which we can generalize this? Is there a way by which we can generalize this? Right? I'm going to take a crude approach here. This is the goal is to convey the message. The goal is not to say that this is the right way to do it. This is to convey the message. What I'm going to do is look at this. I have a text box and I have the member using which, where I am going to update. Yes or no? So the text box control is there. The member is there. The domain member that I'm going to manipulate. Now, if I can, see anyway, this is a string. No issues. This is a string, no issues. What is the only thing that is not a string that will be a little difficult to make you generic is this guy, you agree with me? Isn't it? What will be a little difficult to make it generalize is only that aspect, that particular line, line number 49 everywhere, line number 49, line number 50, no, 60, right? It is only that aspect that will make your job a little difficult to generalize. Now, what Angular gives you to just to make your job a little easy, what Angular gives you is, how do you process an expression that is in string format usually? How do you process an expression that is in string format? Eval, right? Eval, who said that? Are you using eval? Right? Now, the scope object also exposes another method called dollar eval. The scope object also exposes another method called dollar eval. So what dollar eval does is, it evaluates your expression in string format with the context of the scope. Usually, what is the default context of eval method? Eval function. The default context, execution context of the eval function is window, right? Guys, where name equal to Chrome, where EMP equal to an object, okay? Simply say eval of console.log, IAM comma this.name, console.log this.name. What does it say? What does it say? It says IAM Chrome, isn't it? Now, if you take an object and you say name, is mageesh, and you say who am I, a function. And inside this function, typically, I will simply have this. I will simply have this. Usually, I will just have only this. So when I say who am I, I get this, okay? But now, I am bitten by the eval bug. So what I am going to do? I am going to replace this console.log with the eval. I'm going to replace the console.log with the eval. When I do this, when I say EMP.who am I, what is it going to say? How? It is not supposed to, isn't it? This context is supposed to change. I did this earlier. It said Chrome. How did it change all of this? JavaScript geeks, anyone help me here? That's the whole point. Inside eval, your this will be window. Inside eval, your this will be window. That's the whole idea. By default, it will be window. What did I do in the morning? Okay, give me a minute. We'll get back to this. So by default, the context of the eval is window. By default, the context of the eval is window. So typically, what you will do is, you need a way by which you want to evaluate, treat this as an expression, right? Treat this as an expression and evaluate this with the context of the scope. And that is where the dollar eval comes into picture. Look at this, dollar eval, scope.dollar eval, you simply say calculator.basic equal to 20,000. What are you doing? You are evaluating an expression here, is it not? You are evaluating an expression here. When you evaluate it, look for scope.calculator.basic, it'll be 20,000. It'll be evaluated against the dollar, I'm sorry, scope object, the expression will be evaluated against the scope object. So what we will do, we will exploit this. We will exploit this to generalize whatever we had been doing here. How? What I will do, let me go to these text boxes. Let me go to these text boxes and say, use a custom attribute, right? Use a custom attribute to say what is my expression. The attribute name I'm going to use is very unique, app model equal to calculator.basic, right? So for the text box, I am just adding an attribute called app model. And I have said it is basic. Now, HRA, this is going to be HRA for the other text box. This is going to be DA, and for the range, this is going to be tax, right? And that's it, for now, we will stop with this. So app model, I have introduced my own attribute, custom attribute called app model, wherein I just have a string, that's all. An expression, a member, scope member, okay, very good. So how am I going to generalize this? How am I going to generalize this? What I will do, so we will use this as a reference, and then we will generalize it, what? First, locate all the text boxes, locate all the controls that has the attribute app model. Locate all the attributes that has the attribute app model, and dot each, your function. So you will be given with an index and the elements. So this is a jQuery method, and here what we will do, we will simply say, where dollar element is equal to dollar of elements. Dollar element equal to dollar of element, okay. We will take a reference of that, and then let us take this first and foremost, and what is the expression? So I'll say where expression is equal to the dollar element dot attribute of app hyphen model. $element.attribute of app hyphen model, okay, very good. Now, let us implement this. So let's go this and say this is my text box and this is $element bind an event, $element.change, where self equal to this, scope.apply, right? Now this is where I'll simply say this is model, not an expression, that's model, where I'll say expression is equal to model plus a string concatenation. I know this is bad, bear with me, right? And say self.value, right, self.value, and so that gives you the calculator, this one, right? This one has a string, you get my point? This expression that I have highlighted becomes, it is available as a string. Now you know what you can do, you can simply say scope.dollaryval of expression, that's it, this is junk, right? Who said yeah, we'll meet outside. This is junk, okay? Angular doesn't do it this way. Angular doesn't do it this way. Angular goes for a much more elaborated approach to get into this point, right? I am finding a shortcut here. I don't want to go through that elaborate route to reach this point, I am trying to find what is the quickest possible way that by which I can achieve whatever Angular does in a very, very limited scope problem. Are you with me? This approach will not work in a complex scenario, it will not. This serves well for this particular scenario. Let us proceed with our discussion, okay? So this is fine, this is fine. How about this one? Element.change, this is fine. But how about this? Let us take this guy, let us take this guy. I am going to make it as a part of this and say, this is our model, right? We already have the calculator dot basic as our model. So let me take the calculator dot basic as our model and model new value, old value and this becomes what? Dollar, element. This becomes what? Dollar, element, are you with me? Is that clear? So we have added a very, very simple custom attribute and whatever we did repeatedly in each of the controls, I try to bring it, I try to achieve the same thing, generalize it with the help of scope. I try to achieve it by generalizing with the help of scope, is that clear? Okay, very good. Now I don't need any of this. I don't need any of this. Range tags, even this I don't need. This will work perfectly for everything. Are you with me? Shall we verify if this works? If there is an error, we will take a break. So it works, right? It works. So calculator dot basic. It is loaded perfectly fine. What happened? Here I entered the data in the basic and I try to access it from here. I wanted to make sure that the changes made here reflects there. Now, if you want to know, right? So we'll say scope.$watch of a function, no. Calculator.basic, calculator.basic and say function and simply say calculator. I'm sorry. Do a console.law. Console.law, calculator.basic changed, right? Now when you type 2000 here, you will find that it prints calculator.basic changed, right? So whatever we attempted to do across multiple controls, we just brought it in using one generic functionality. Okay, very good. Now let us look at this. Look at this, this part of the code. I'm going to take this, I'm going to take this and make it as a part of our button. So where is our button? Here is our button. So in the button, let me add one more attribute. App-click is equal to the same expression whatever I gave earlier. Is that clear? So I've said app-click is equal to calculator.calculate. Whatever we did it in the code, I have moved it into the HTML. I have moved it into the attribute. Now let's go here. We will automate this, we will generalize this. So dollar off, find out everything that is decorated with app-click. Find everything that is decorated with app-click. Dot each, your function that takes index, elements. And here, what do I want to do? Exactly, look at the element. So where dollar element is equal to dollar off element. And the expression is equal to dollar element.attr of app-click, dollar element.attr of app-click. I simply need to call the expression. So how? Scope.dollaryval of expression. But what am I supposed to do? Any changes that you are making, make sure that you are doing it inside. Dollar apply, exactly, right? Dollar apply of a function, do this. Make sense, right? So now let us save this, break this, remove this. Let's go back, reload it here. And I'll say, okay, let us subscribe to the salary. Salary, calculator salary, and calculator salary changed. And now, okay, hit this first. Subscribe to this. Now give, you see there? Calculator app, app-click. I need to attach the event handler to the click, dollar element dot click off the function. This is where everything has to happen. Dollar element is missing, where element is equal to dollar off. I think I need a break, dollar off, element. Let's go back here. And let's say, right, so 2000. And now, let's come here, watch for the salary and say calculate. It says, calculate a salary changed. You are able to trigger that. How about this? Now, the difference between this and the text boxes, the text boxes are two-way. So you make changes to the text box, it has to update the model. Whenever the model changes, you have to update the view. You have to update the text box. The text boxes are two-way. Whereas here, the controls, if you look at what we are doing, you are using a span and a div. And this is what? Only one way, right? This is one way. So whatever we did in the text boxes, we can do it right here. And to do that, I'm going to take the span. I'm going to take the span and say, app-bind. To differentiate that, this is similar from your model implementation. Model is for two-way, and this is going to be for one-way. So to differentiate from the model implementation, I'm simply taking app-bind. And in the bind, we will say, calculator. Calculator.tax and take the same thing and update it here. Calculator.sailory. Calculator.sailory. And this, I'm going to slightly change. How dollar off, ask risk, locate everything, that is having an attribute, app-bind. Each of a function, index, element. And here, I will say, dollar where, dollar element is equal to dollar off, element. And then, the expression is equal to dollar element.attr of app-bind. Take the expression. And then, say scope. And dollar watch of the expression, a function, new value, old value, when it is changing, simply, simply say, dollar element.html of what? New value. That's it. Of the new value. We are done. So now, I don't need this. I don't need this. Now, run this. And it works perfectly fine. Are you with me? And whatever we did, nothing is specific to the calculator. Make sense? Really? Thank you. Right? Now, all I need to do is, take this code, put it in any application, not in production application. And just use the corresponding attributes. My application will work perfectly fine. Is that clear? So, before even we go about creating the scope infrastructure ourselves, right? There are a few more things, the times I would like to add. Number one. How does Angular internally organizes your application? How does Angular internally organizes your application? So, what I will do, I'll solve the same problem using Angular. Is that clear? For the sake of others to understand, I'll solve the same problem using Angular. And then we will move on. So, index hyphen and here, two ints. As I said, I don't have to do any of this, right? I don't have to do any of this. Then, what am I supposed to do? If I don't have to do any of this, what am I supposed to do? What I am supposed to do is this. We will say where myApp is equal to Angular.module of myApp give a name, comma nMTRA and then say myApp.run a function $rootscope and you say $rootscope.calculator $rootscope.calculator and this is what all the code that is expected from me. As of now, this is what all the code that is expected from me. I don't need to write any other code. Now, I can simply say ngApp is equal to myApp and wherever we have used AppModel, right? Wherever we have used AppModel and AppClick and AppBind so wherever we have done any of those things I will simply need to replace it with ng. I have to simply replace it with ng. That's all. So that is what all it takes for me to run this application. So let me run this application, open it in the browser and let us see if this works. There you go. It works. So all I am doing is only this. That's all. Now, what am I doing here? What am I doing here? I am creating a module and the module exposes a method called run method to which I pass a function as an argument and what is that root scope? What is that root scope? So whatever I did, as I said earlier whatever I did is just to give you a glimpse of what you can do with scope but that is not all and that is not how scope works. That is not how scope works. Then how does it work? How does it work? Now Angular doesn't stop with giving you one scope object. Angular doesn't stop at giving you one scope object. It gives you a hierarchy of scope objects. It gives you, it is capable of giving you more than one scope object. Now, if you take an application, right this is why I feel power points come handy. That's okay. Now, let us take an application. So if you assume that this is the application and this has several regions. So you have this region and you have another region and you have another region and inside that you have two other regions. So this is one and this is another. Right? Now, you will typically have applications that show data, loads and loads of data. Yes or no? You have applications that show loads and loads of data. Now, if you have only one scope object accumulating that scope object with all the data might be a little problematic for you to manage your application. Definitely there is no performance gain but this is primarily in terms of the aesthetic nature of how you do things. So I don't want all the data to be to be put in one single scope object. I don't want all the data to be put in one single scope object. Then, what do you want? What do you want? If you don't want one single scope object, then what do you want? I want multiple scope objects. Okay. Now, when you have multiple scope objects, how will you use them? When I design my application like this, you will realize that the moment I use different colors for different regions, it means that the data related to this section bound to change together. They are closely related to each other. They are bound to change together. You agree with me? Exactly. That is why we split them into different regions. So the data related to this section is bound together. The data bound to change together. The data related to this section is more likely to change together. This is more likely to change together. This is more likely to change. Now, what I can do is very simple. All you have to do is you can ask Angular, hey, you know what? I want different scopes. Get me one scope here and then another scope here and another scope here. Some part of it I want here and some part of it I want here and one more here. Okay, very good. Fine. Now, if you ask Angular, I can simply go about creating scope, scope, scope, scope, scope. No issues with me. No issues at all. But the challenge is can those scope objects be completely isolated from each other? Should they be completely isolated from each other? If you look at the data, if you look at your application, right? Even though the colored regions change together, they are not completely independent of each other. You agree with me? If the data makes it as a part of your application, it means that it is one or the other way affected by other parts of the application. So it is neither this extreme nor that extreme. Then how can I manage the relationship among these scopes? These scope objects need not or should not exist completely independent of each other. They should not completely exist independent of each other. There has to be some relationship exists among these particular scope objects so that later when I want it, I can very well use them. What kind of relationship? What kind of relationship that can exist between these scope objects that are created for your application? Exactly. If you think about it, the purpose of the scope object is to serve your view needs. What is the purpose of the scope object? It is to serve your view needs, the needs of the view. How is your view organized? My view is organized in a hierarchical nature. So it is more fitting to say that the scope also has to be organized in a hierarchical nature and the starting point of that hierarchy is your root scope. Okay, fine. Hierarchical nature is fantastic. I am able to create a hierarchy of scope objects but what is the relationship? Basically the way Angular organizes its scope object is when you create a hierarchy the child is a prototyping inherited version of the parent. The child is a prototyping inherited version of the parent. The relationship is inheritance. It is not just a reference it is inheritance. Some of the design decisions are the beautiful decisions in Angular. So because you have this relationship maintained as an inheritance, the advantage is if I want something common right, so if you look at here S4 and S5 can very well inherit what is that in S3 and this is my root so this is where my root is now S1, S2 and S3 can inherit whatever is there in the root. Can inherit whatever is there in the root. Are you with me? Okay, very good. So the point is your scope is not maintained as one object even though I demonstrated something like that but your application allows you Angular allows you to create a hierarchy of scope objects. Hierarchy of scope objects. Now one advantage of it is that you can very well check whether the whatever is there in the parent is automatically accessible through the derived child scopes. The other advantages the other advantages we said dollar watch and dollar apply. We said dollar watch and dollar apply and we realize that whenever you call dollar apply the corresponding watcher function is called. Yes or no? How does it do? Basically Angular does a dirty check right? Angular does what you call as a dirty check. So what is a dirty check? Basically whatever function that you are attaching. Whatever function that you are attaching it calls the function and checks hey have you changed have you changed, have you changed and if it recognizes that it has changed then it calls the corresponding watcher function. It calls the corresponding watcher The process of recognizing the changes and then calling the corresponding watcher functions is what you call as what? A digest, right is what you call as a digest. So you trigger saying that hey you know what? Start iterating through all the watches, all the bindings and then check if they have changed, if they have changed call the corresponding watcher functions, call the corresponding watcher functions and this process is what you call as a digest process. This process is what you call as a digest process, okay, here is the catch and this is where many a times angular falls short. What is it? When the digest cycle is triggered, you call this as a digest cycle. So when a digest cycle is triggered, it does not stop at one scope, it goes through the complete scope hierarchy, right, it goes through the complete scope hierarchy. So if one scope is internally depending on the parent scope, when the parent scope is changing automatically this child's scope will also trigger the digest cycle so that if it has to react, it will automatically react, it will automatically react. So all it takes is just one simple trigger process that will trigger the complete digest cycle from the root scope to all the children's scope and thereby a dirty check is done and it starts calling the watches, are you with me? This is what is happening with this scope, we have just covered 1.5% of angular, right, this is what is happening in scope, alright. Now there are a lot more things, what are they, angular comes with a very, okay, so every time you do this, let me see who can answer this. Every time you do this, ng bind equal to calculator dot tax, ng app equal, I mean ng model equal to ng click equal to, right, what are you actually subscribing to the dollar watch? What are you actually subscribing? In our case, I took it as a string but in angular what happens is this is parsed, this is converted into an expression and a function is what is being passed to the scope object, a function is what is being passed to the scope. So you have a scope and then you have a very, very powerful parser, as a matter of fact the next most important thing in angular but that is not very much visible like scope is parse, the dollar parse, dollar parse does everything, all the flexibility that you get by declaratively doing everything in angular is as the result of hard work done by parse, as a result of hard work done by dollar parse. So when time permits, take the dollar parse service code and go through it, it will be very interesting to see, right. So the parsing takes place and then you have your, what are these? These are what you call as directives, these are what you call as directives. So what the directives do, the directives bind your angular scope with the actual DOM, they act as a bridge between your DOM hierarchy and your scope hierarchy. So you have a DOM hierarchy and on top of it you have a scope hierarchy that is specific to your application and it is the directives that connects the bridge between these two. So that the directives make sure that anything that happens in the scope updates in the DOM and anything that happens in the DOM updated in the scope. So the connecting part, connecting bridge between these two is your directives, right. Okay, now, so in essence, in essence this is what is happening in angular. So you have a module, you have a module and the module takes care of, module, what is the role of a module, anyone? A module acts as a container, it acts as, it is a logical container is fine, namespace, whatever you said, that is okay. But in essence, a module is a DI container, it's a container for your components and the actual injection is done by another service called dollar inject, right. So there is another service called dollar injector that takes care of the dependency injection. So you have scope, you have dollar parts and then you have the dependency injector and then comes your directives, providers, blah, blah, blah, blah, all those things comes next, right. So I just wanted to give you at a high level what Angular offers for you to, so that you can enjoy this flexibility, so that you can enjoy this flexibility, okay. Now let us jump into creating a scope infrastructure, let us jump into creating a scope. Now we saw that, we saw that the scope is what? It is a plain simple object, right, we saw that the scope is a plain simple object. So if it is an object, what we need, what we need is a class, what we need is a class, right, a plain simple class, scope, okay. Now what does the scope take? The scope has one method, what is it, dollar watch, is it or no? The scope has one method, dollar watch, so scope dot, rototype dot, dollar watch is equal to a function that takes a watcher function, that takes a watcher function, we have used a string version, internally the string is converted into a function, in Angular internally it is the string is converted into a function. So we take a watcher function and then a listener function, we take a watcher function and then a listener function. Now what do I want to do, what do I want to do with this? Very simple, I need to accumulate this somewhere. So I'll say this dot, dollar dollar watchers is equal to an empty array. And then here we will say this dot, dollar dollar watchers dot push what? The watcher function, this dot dollar dollar watch, push, dollar dollar watchers dot push the watcher function, okay, very good. Now we have got the watcher function. Now the process of triggering the dirty check, right, the process of triggering the dirty check is done by what? Done by the digest cycle. So if I have to write that, so dollar scope dot, prototype dot, dollar digest is equal to a function. What am I supposed to do, right? I am supposed to simply, right, okay. So when I am pushing this watcher function, right? I don't want just the watcher function. I also want the corresponding listener function as well, very good, right? I also want the corresponding listener function. What was I thinking? So where watcher is equal to an object where you say the watcher function is equal to the watcher function. And the listener function is equal to the listener function. And then publish the, thanks, thanks, sorry, right? Watcher function and listener function and publish this, okay, very good. Now when you call the digest, all I have to do is take the watchers, dollar watchers, where watcher, yeah, right? Take the dollar watchers, iterate through each of them, is that clear? And then call the, exactly, right? So now for that, I need to know what is the values? But how will I detect whether they are changed or not? Apply is an entry point. This function need to be invoked only when you do apply, fine. But you need to have the dollar digest, isn't it? You need to have the dollar digest. So what you typically do is when you add this, let us also take this. I will call the watcher function dot old value equal to invoke the watcher function, are you with me? I'll simply invoke the watcher function, am I making sense? With the context of what? With the context of this, the current scope object. So that will give me what is the old value, okay, very good. Now, I will push this. When I perform the digest cycle, I will say where? Take each of the watcher functions. This dot, dollar-dollar-watchers dot for each, take one watcher at a time, take one watcher at a time, and simply first check what is your new value? New value equal to watcher function, invoke the watcher function, pass this context. And if the old value is not equal to the new value, if old value is not equal to the new value, then what am I supposed to do? Call the watcher, oh, sorry, thanks, sorry, sorry, sorry. We'll take the watcher dot watcher function, watcher dot watcher function, and because I am invoking it, I need self equal to this, and then watcher function of self, watcher function of self. If old value is not equal to new value, then what are we supposed to do? We are supposed to invoke the corresponding designer function. So watcher dot designer function invoke it with the new value and the old value. Am I making sense, right? And then set the watcher dot old value is equal to new value, watcher dot, one second, one second, just give me a second, where am I adding it, watcher function, this is watcher. We will have it in the watcher object itself. We don't need to be attached to the watcher function, watcher dot old value equal to watcher dot new value, new value equal to watcher, okay. I think we are good now. What is it? If watcher dot old value is not equal to new value, watcher dot invoke the listener function and then call the old value, and then call the old value. Make sense? I'm sorry? We, yeah, thanks, thank you. New value comma watcher dot old value. So invoke that particular function and you set it. Make sense, right? Now, all we have is a plain simple digest. All we have is a plain simple digest. Now, when I do a dollar apply, what all I am doing? What all I am doing? So scope dot dollar apply is equal to, I'm sorry, prototype dot dot dollar apply is equal to a function that takes another function. That takes another function. And all I am doing is invoke the function and try invoking that particular function. And finally, irrespective of whether it was executed successfully or not, I'm going to say this dot. Now you understand what's happening in dollar apply? That's it. All it does is just simply calling the, I hope you enjoyed it. It was useful. Okay, thank you.