 introduction about myself. I worked as a senior engineer at LinkedIn and before LinkedIn I worked for many different companies but my very first Amber experience comes from Yahoo back in late 2013's. After Yahoo I worked for Apple where I didn't do Amber stuff but that was not for long. The love for Amber pulled me to LinkedIn and here I am working on a lot of cool Amber stuff. Also when I'm not doing any coding related stuff, here are the things that I love. I love playing guitar, not a pro but I can still play a little bit. Cricket fan. For those who don't know what cricket is it's a sport which is very similar to baseball and I myself play cricket and it's very famous back in India. Off late I have this craze of building my own custom mechanical keyboards with new switches and custom keycaps etc. If any of you have any cool ideas feel free to reach out to me now watching movies and who doesn't write. Okay enough said about me now we should focus on the main topic. So today's agenda would be something like this. I plan to cover the journey of Amber JS in terms of its versions like version 1.x, 2.x and 3.x. Going forward I'll be talking about Amber Octane and its native concepts like some core concepts like native classes, glimmer components, templating and octane track properties, modifiers and decorators. After that I'll be showing you a consolidated comparison of the classic syntax versus octane syntax and at the end I will leave you guys with some documentation and references to migration guides and some information about amber octane blogs etc. Okay so let's start with the journey of amber but before that let's take a step back and think about around 2013 times or so. Back in that time we didn't have a lot of options in relation to JavaScript frameworks as we have today. The most evident options during that time were back both JS, AngularJS, KnockoutJS etc. While these were great they still left the decisions of configuration on the developers. It was during that time when one framework emerged which was built on the principle of the developers should not care about the configuration stuff. They should only focus on app specific stuff which means the developer's productivity would be increased because the framework would do the configuration stuff. The name of this framework was AmberJS. Amber has come a very long way ever since 2013 and let's see how it started with 1.x. So since 1.x was the very first version of amber it came with a lot of goodness. To start off with is convention of a configuration. This was a whole new mental model shift for any developer who comes from a different javascript framework world. I will give you my specific example. I came from backbone JS background and when I started working on amber it was very different for me but as and when I started working on amber I started feeling the difference and I started appreciating it more and more because I started feeling more and more productive. So that was when I started falling in love with amber. Also amber provided inbox built-in routing capability. So that means you don't have to write your own routing layer or get it from outside or something like that. It was already ready for you which was a huge thing. Also we had support for amber data that took care of the state of the application etc. And 1.x was built on new driven architecture. What I mean is here you can see the route controller view. That was the path that or that was the architecture that we followed at that time. And for anybody who wants a refresher of how we used to write amber views a sneak peek is in here where computed properties were written somewhere like we annotated it with dot property and observers were written something like very added dot observes to the properties. Also we had the capability of two way bindings which was great because at that time it was really really to have this ability. Attribute bindings this was really good because let's say if you had a backing JS class for template like a component with a template or view with a template and you wanted to associate the attributes value dynamically. So with bind attr syntax you can associate your components or views property directly on the template. So that was pretty good. Okay, so this was a good amber 1.x was really taking off and it was doing great and complex web applications were starting to love it already. But the community always believed that there's always room for improvement. So the lessons that they learned from 1.x frameworks that were evolving during the time when 2.x was being planned out, they embraced all of these things together and added things in the roadmap of 2.x. So here are the few things that landed in 2.x. Instead of view driven now we are component driven. This was because the web community itself was going in that direction and amber was hand in hand with that. So here you can see route controller component is of new way and again a sneak peek of how the syntax changed. The computed properties now amber.computed and observer is now amber.observer. Also we had the glimmer rendering engine in 2.x which was a very very good thing. It gave a dramatic improvement in the re-rendering of the application. It's pretty good and then we had better binding attributes like you remember in the previous slide. I showed you the bind data syntax like you can see here as well in 1.x. But this posed some issues where it became an overhead and it was confusing and so on. With 2.x it became more simplified where you can directly add a property from your JS class onto the template without adding the bind data. So that was nice. Also the template scoping was improved. Let me show you an example. Here we have 1.x and 2.x again a comparison and I want to specifically talk about the second example in the 1.x section where we are iterating over the posts without any in. So here I am doing each posts and whatever is inside of that iteration loses the outside context or it doesn't have access to the outside context. So you are stuck in that iteration itself. So as a workaround the above example like each post in posts allow you to do that where the post would act as the inner context and then you can easily access out your context. But in 2.x things are way more simplified and standardized where every time you want to iterate over a property you use the as functionality like each post as and then pipe and whatever the parameters here it is post. So again the post would be the inner context and you can get the outer context as in the new wish. Also while 2 way bindings was great it did impose some issues when your app started becoming more and more complex and more and more bigger. By that what I mean is let's say property a updates b, d updates c, c updates a again. So this kind of infinite cascading started becoming a problem and that's why we started embracing the data down actions of approach. 2.x was not just about all of this it was way more than that. In 2.x itself we had a roadmap towards things like HTML syntax for component invocation routes to drive components like these are angle bracket invocations and routable components if you might have heard already. That brings me to my next topic which is Adverse 8.x. This is very exciting it has a lot of things I'll mention a few of the things here but there are many more things than this in 3.x. To start off with it's cleanup cleanup cleanup. Why am I emphasizing on cleanup so much because a lot of cleanup has been done with this version where a lot of private API's deprecations everything has been cleaned up in that way the code the framework becomes more manageable, maintainable and more cleaner. Also we have removed support for Internet Explorer 9, IE 10, Phantom GNS and also Bower. Points I will be explaining more in details in the coming slides so I'll quickly skim through these. 3.x has the ability for supporting native classes, glimmer components, angle brackets invocation, track properties, modifiers and decorators and lots of documentation which is a huge thing when you are moving forward with a such a huge change so that is a job well done by the folks. So what did we learn? We saw that framework emerged in 2013 and released 1.x and then it improved more in 2.x and then it improved even more in 3.x and then here we are with the first new edition and we are obtained. So you must be thinking why is this a new edition and why is it not a new version. So you can think of an edition as something that represents a shift in programming model due to new features and concepts added in the framework. Like for example here we have a bundle of new features, a lot of documentation, a lot of tool links like code mods etc. Everything bundled together so that's why it's a new edition. So let's take a sneak peek of each or some of the key concepts of AMBER octane itself. Let's start with native classes. So AMBER relies very heavily now on native features of JavaScript. When I say it relies on native features I mean there is very less framework-specific code and because there is very less framework-specific code the overhead on building the framework itself is very less. That means increased performance and AMBER is known for its steep learning curve. I mean I've seen many folks who have spoken to an editor, I did some blogs as well, where people choose not to use AMBER because of its steep learning curve and I can imagine why but I think with octane that won't be an issue anymore because since now we have again I'm repeating less framework-specific code so you don't have to learn a lot of things out of the box. So it gives you a smooth learning curve experience. Also because again the same thing it's more native stuff, it is more aligned with the JavaScript community and you can share code more easily and there is no more dot gets. Can you imagine like me, myself, personally I used to feel like why do we have this like this dot get foo, this dot get bar. I'm sure a lot of you must be sharing the same feeling like I am right now. So there's no more gets. You just directly do this dot foo, this dot bar like you usually do to property in your JavaScript currently and of course it is clean and easier to read. In other words, let's see an example. So here in this example you see on the top we have this classic AMBER object syntax and at the bottom we have native syntax. Now if you see the main difference is how we are creating or defining the object on the top we are doing AMBER object dot extend but at the bottom with native class syntax no more AMBER objects. You can just say class person, that's it, you're done. Also in the classic syntax you can see the computer property full name is created by passing in the property's first name and last name and we are invoking the first name and last name is this dot get first name, this dot get last name. Whereas in native class we are just writing the native getters of JavaScript and then just adding a little splash of computer decorator on top of the native getter, that's it, you're done, you don't have to do this dot gets anyone's, this is your first name, this is your last name. So that's pretty cool. This is a little bit about native classes. Now let's move on to Glimmer components. In my personal opinion this is one of the biggest wins in AMBER's journey so far because AMBER's component library was pretty old and with this new component library it's a great refresher. Not only does Glimmer components take all the goodness of native classes but it also makes it more simplified component library in AMBER. Let's talk about this following example again. So here Glimmer component is defined by importing Glimmer component instead of AMBER component as you can see and instead of exporting default component dot extend like we do usually in our classics syntax we just do a native class and then extends the Glimmer component. Also there are now fewer hooks and properties that is a great thing like previously we had 13 lifecycle hooks and 29 properties. Now can you imagine a new person coming and joining working on AMBER and you say hey if you want to be productive if you want to start working and make an effect you need to know 13 lifecycle hooks and 29 properties that would be immediately daunting and overwhelming for anyone who comes across this. I think with this with Glimmer components no more fear because now we only have two lifecycle hooks and three properties. Also you must be already knowing that every time you create a component in the classic component world a wrapper is always wrapped around your template like for example here the number of guests is just a value but when it renders on a DOM there'll be a div or in this case there'll be a label that will be wrapped around it. This might become confusing and it has actually I've had many people come to me and ask me hey I'm just rendering this template what is this new div that is being wrapped around it I'm not even adding it in my template and then I had to explain them the reason why but with glimmer components it's what you write is what you get or what you see here you can see very well the bottom when I'm wrapping it around with the label tag itself so I'm not doing anything special in my class rather I'm just adding everything in my template itself so that is amazing also it's important for us to identify what things are local in our component and what things come from outside with the classic components there was no way to do it because like you can see here this dot number of guests and this dot max guest they both are this dot and this dot there's no way for you to know which is a current one and which is and which is a local one and which is coming from the parent context but if you see in the glimmer component case this dot r's dot max is so I know now for a fact that max guest is coming from somewhere outside so it's from a parent context so that is a great way to identify what is the point of origin for any particular property so this is a little bit about glimmer components for you guys now let's talk about templating in octane now there are a lot of good things that have come in in the world of templating for octane let's start with angle bracket syntax now this angle bracket syntax is a dramatic simplification of api like let's say for example in here in this example we are seeing in classic templating we are invoking the component using the curlies but in octane we are invoking the component using the normal html syntax which is angle bracket so now it's very easy for me to understand which thing is coming or which thing is a component which thing is a helper which thing is a property whereas before it was very hard for me to understand right when I see it from the first go also with angle brackets we have something called as named arguments named arguments are a way where in the previous slides we saw this dot r's it is similar to that but in the templating side where it helps you understand where is the origin of your property coming from for example in here on the top everything has no context whatsoever you don't know where the employee name is coming from you don't know where the employee id is coming from but in the bottom it's very clear like for example the employee id when i'm prefixing it with the at the rate symbol i know that it is coming from an outside context so now i can understand that okay this is a pas de nard and not something local to my javascript class also a good thing to keep in mind is on the left side like on the classic templating side on the left side we have name mid and add employee now it's hard to understand whether this thing is part of the html attribute or is it a part of your component but with octane it's very easy because now everything that is pertinent to your component will be always prefixed with an at the rate like we have right now in here also we have required this in the templates like we have at the rate symbol for something coming from outside we should know what things reside locally in your backing class and that's where this dot employee name becomes very handy before there was no way for me to know but now i do so it's a great way to make things very specific and very concerned and very clear so this was a little bit about templating in the octane world now let's move on to track properties my personal favorite the reason being the simplification that it brings on the table but beneath it is very strong let me start by going through the syntax real quick here you can see instead of computer property when it importing on the top i am importing a track property from glimmer tracking library then any local property that i want to listen to or that i want to depend on i will mark it as track like i'll prefix it as as track in the track syntax the magic happens on the top in classic syntax you can see there's a computed property that is depending on force name and last name whereas the bottom i'm not doing anything it is a simple plain javascript getter but the magic happens now where any property that is marked as tracked will make sure that any getter that uses that track property and if there is any chance where the track property changes it will make sure that it recalculates the getter and sends it back to the browser so in a way the functionality or the behavior would be similar to computer but this is way better just imagine when you are writing a huge component class and you have several properties in your class and if you have to depend on few of the properties here and there for multiple computer properties there'll be so many computer properties in your class and it will be not very clean but with this you can just mark those or prefix those with track and just write your regular getters that's all so very clean and concise as well also no more sets like in native classes we have no more gets now we have no more sets so no more this dot set full set bar or for example in here this dot set count equals this dot get count no longer all this confusion just do what you regularly do in your JavaScript this dot count equals this dot count plus one and you're good to go so that's amazing so these are a few things of track properties how it works and how it behaves now let's move on to modifiers and decorators so what is a modifier you can think of modifier as functions or classes that are directly applied to the template like it's applied directly to the element itself like you can see in this example on the button tag i'm adding the on modifier itself which is just doing some usual event handling with this jordan increment now you must be thinking why do i need to do this i can currently with my dick insert element hook i can associate my event listener and i'm all good to go but just think about it you can do that easily with your top level element or the root level element for your component but what about the child elements you could still do it but it will be a bit messy instead of that modifiers allow you to target specific elements so you can go in whichever elements you want to associate things with you can just add the modifiers in there directly and moreover it also cleans up the code for you and it also i mean cleans up the state and registers if any parameters ticked so that is a great thing and they are easy to reuse so there are a lot of benefits of using modifiers or not using them now let's move on to decorators what is a decorator now you can think of decorators as something that enhances the functionality of what it is prefixed on for example here you can see the increment function and decrement function has action decorator prefixed now just the increment and decrement functions are doing the job of incrementing or decrementing the counter but with action decorator it's doing more than that it understands that oh now this function is becoming an action handler rather than just being one function so that's how it enhances the functionality so it's kind of an abstraction for the developer but it adds a lot of value so this was a little bit about modifiers and decorators now let's move on to the meat part now we will do the comparison between the classic and the obtained syntax now here on the left very very left side you see there is a custom off label that's what we are talking about right now it is invoked using the curlies like you can see in the bottom with toggle label and I'm passing in few arguments and in the right you can see the actual implementation of this component all this is good this is classic component you can see a lot of things happening in the component as itself when I move it to obtain this is how it looks like now the template specific stuff is in template the component specific stuff is in component and you can see it is invoked using the under bracket syntax let's go through it one by one so right away you can see that the import is different on the left on the classic side we have component under component and on the right side we have glimmer component next we are no longer doing the classic component syntax like on the left we see component.extent but on the right we see native class syntax and then we are extending from glimmer component then no longer implicit wrappers on the left I am overriding the tag name with label but on the right if you see at the right bottom the label element is being enclosed in the template itself also any template specific stuff goes to template itself on the right in the obtained part but that's not happening in the classic we are still doing attribute bindings and class name bindings in the JavaScript class also a few things to note on the left side in the classic syntax we have a property called is awesome and a label value of computed property that depends on that and then we are invoking and using this .get but on the right instead we are prefixing it with tract the is awesome and then we are just using a normal regular getter and no longer this .get it is just this .get awesome next thing to check is on the left we see that we are depending on a property called value but I don't know really where this value is coming from but on the right it's very evident that it's coming from this .r this .value that means coming from parent context so easy to understand also on the left we can see that we are handling the click handler on the left by writing the click handler in the classic syntax but on the right we are using the on modifier to make sure we are hitting on the element itself like registering it and then handling it using the actions decorator so this was a little sneak peek for you to give you guys the feel of how it was before how it is now how simplified and how um good the separation of logic has happened now and I hope it gives you a good understanding of what is coming forward as promised here are a few reference and guides where it would help you to migrate your current existing amore to octane like with these code mods we have a lot of code mods in this link that you can follow the folks have done a lot of hard work and it is easily seen in there hopefully this will be a very smooth transition for you guys also if you have any questions about migrations or migration order or something like that amber atlas would be the right place for you to go because it will give you the right amount of information for you to migrate very smoothly and the rest are a few random information for you to dig down more deep into octane and its key concepts and deep understanding about each one step so this was it guys thank you very much for patiently listening to my talk and I hope all of you are as excited as I am for octane and I'll see you writing octane right away thank you