 Hi everyone, my name is Ming and I'm an engineer at Intercom. Today I'm going to be talking about my experience learning Ember and becoming a software engineer. And what I think are the most important concepts for a beginner to internalize. So before I start, a little bit of background about myself. I'm fairly new to working in tech. I've been in tech for about two years, but I'm even newer to software development. In fact, I think it was nearly a year ago to the date when I made my first commit to Intercom's Ember repo. So I studied applied math and statistics in college and then spent some time working as a commodities trader, trading agricultural commodity futures like corn and lean hogs. My first role at Intercom was actually in data analytics. And I did that for a while before getting bit by the software development bug and realized I wanted to make things and started my transition to engineering. So this is all just to say that I had a lot to learn in a really short amount of time. Previous to this, I had no experience building stuff on the web. And Intercom had a very generalist engineering culture. So most of our engineers worked across the stack. It was also quite a big team. We have around 230 employees with an engineering team of 70 people and also quite a complicated product. There was like four different products within the larger Intercom platform and they all kind of interacted each other in different ways. So I wasn't stepping into this really simple, easy code base. And at the time when I was making my own transition, Intercom itself was also undergoing a change because they were transitioning from using Rails on the front end to using Ember. So I too was caught in this wave where I had to learn about software engineering principles and web development and Rails and Ember all at the same time. So from having just gone through this journey myself, hopefully this talk can help others who are just starting their own Ember journey as well as give some ideas to people who are probably more experienced who are now mentoring or teaching others. I want to talk about three steps that you need to take to successfully make such a transition from a non-engineer to a Ember product engineer. So the first thing that I think you have to do is learn how to embrace frameworks. When I started this whole process, I knew how to program. I had had experience thinking algorithmically. I knew what an if statement was. I knew what a while loop was. But at the time I really only had experience writing really small ad hoc scripts to analyze data or to make data visualizations. And while these line by line imperative programs can teach you a lot about programming and from there using more advanced patterns like functional programming or object oriented programming allows you to do more complex things like build checkers, if you actually want to make something, if you actually want to make a product without having to make loads and loads of decisions, sooner or later you're going to have to turn to a framework. And that's because ambitious applications require structure. As you add on more developers and add on more complexity, having constraints and a standardized set of opinions really simplifies the development process. And actually one of the main reasons at Intercom, the main reasons why we switched from using Rails to using Ember was because we were sick of having every developer bring to the front and their own independent ideas of how to build things there. But to be effective within a framework like Ember you have to learn what the Ember way of doing something is. You have to learn what its opinions are, what its quirks are. And I remember in my really early days of learning Ember I was working with this, I was writing some code where I was writing a computed property that was dependent on how many, how long an array was, how many elements was in this array. And so here's kind of like a simplified version of that example. So I have an array called invoice IDs and a computed property called number of invoices that just got the length of that array. And somewhere else in my code I was pushing elements onto the invoice IDs array. And I remember spending like a really long time just trying to figure out why wasn't my computed property updating and I couldn't figure it out until my manager came and pulled me, oh, you have to use observer friendly methods for this to work. So just in that phrase, okay, observer friendly methods, you first have to know that observers are thing in Ember. Okay, easy enough. But then you have to know that they only react to certain types of methods and that plain old JavaScript push isn't one of them. You know, for this to actually work for it to get updated, you have to use push object. Now none of this is particularly difficult to grasp, but they're just things that you need to know in order to be effective. And kind of related to that, when you're a beginner learning software engineering through a code base that uses a framework, one thing that you hear people say a lot is this concept of magic that is just inherent in all frameworks. And when I say magic, I mean like implicitness. And I think that when you're teaching someone as a teacher, it's really important to reveal how the magic is done. Actually say explicitly what the framework is abstracting away. And this is especially important at the seams between frameworks. So recently there was this really great medium post written by Alan Cooper who's the father of Visual Basic that talked about this concept of edge calculus that complexity exists where two systems interact with each other. And I definitely think that holds for web development. So in the case of something like this, where Amber talked to whatever powered your app on the server side. I remember one of my first Amber projects was this really simple internal app, which I'll talk about in more detail later. But it was a really simple app where you could search for a customer by their name or by their ID. And then from the search results, you could click on the search result and view a customer's profile and view some information about them. And it was a Rails backend plugging into Amber and Amber data on the front end. And because I was using Amber data, rather than having to write code like this where explicitly writing out an Ajax call, I got to use the store methods. So this.store.findall, this.store.findrecord. And it sounds really silly. And as I was writing this talk, I was actually debating whether to put this in here or not. But as a beginner, I didn't know that the various store methods mapped to specific endpoints on the server side. I didn't know that they mapped to these methods in my Rails controller. And I think that was partially because of the convenience of Amber data. Amber data abstracts all of this away. And that's great because then you don't have to write this whole big long thing where you're explicitly writing out the URL, writing out the action. Instead, you can just use these relatively simple methods. But then what happens is that it's less clear the interactions between Amber and what's happening on the server side. So I guess the takeaway lesson from all of this is even if your code isn't being explicit, your understanding of it has to be. The second thing I want to talk about is that I think the second step that you have to learn and internalize is learning how to navigate the component hierarchy. So I think the existence of components in Amber is really good for beginners because it reinforces a lot of general good engineering practices like modularity and usability, especially in an app's presentation layer, which is an area that can get pretty messy pretty quickly. But I think working with components takes a little bit of getting used to as well, especially if you're working in a large app. You know, following call stacks is definitely a little bit of a learn skill. And I think this is because the number of components that an app can have can get very large very quickly. So just to kind of illustrate that, I have here a screenshot on the left taken from Intercom. This is part of the message composition flow in Intercom. It's the UI that you see when you're selecting who to send your message to. And on the right, I have a screenshot taken from the Amber Inspector in the browser that lists out some of the components, like part of the components that are on this page. Now all these components here listed on the right only serve to power this tiny little section of the select. So you can imagine if I were to show you the entire component hierarchy, how deep the rabbit hole can go. And when you have a lot of components, the debugging process becomes something like this. So first, you notice that something is wrong, some unexpected behavior is happening. So you have to find where is that thing showing up, what component is it in? Once you find that component, that variable that's driving this behavior, and then you have to check if that variable is being passed into this component or if it's being computed there. Now let's say it's being passed in. Okay, now you have to control F through the code base with this component's name, trying to find the component that's rendering this component, and once you've found that parent component, what are, is that variable being passed into the parent component or is it being computed there? If it's being computed there, what are the variables that are driving it? It's being passed in, so on and so forth, kind of repeating this up the call static until you find the source of your problem. And to be perfectly honest, I definitely found this a little bit strange and it was something I wasn't used to before I started working with Ember. And this isn't the only place where we see this pattern. A similar thing could be said about action bubbling. If you're making a close button on a modal, despite writing the code for the close button itself in the template for that modal, the action, once you follow the calls of this.send action four layers up, the code that's actually closing the modal lives in some route five folders away. So I guess all this is to say that you have to get comfortable with the idea that where an action is taken or where a variable is shown is very far away from its source code. So in order to be successful building things or debugging in Ember, you have to learn how to hold state in your head. So the last thing I think that people should learn is to learn to love Ember URLs. I love Ember URLs. I think Ember's opinions on URLs are one of the best constraints that the framework has. And thanks to Ember CLI, there's now a really strong link between the layout of the page and where the code lives in the file structure, which brings this holistic level of organization to Ember applications. And the fact that Ember URLs store the state of the application means that people are forced to think about, you know, how the UI of the app and how the code that powers it are linked, marrying design and engineering. And so to kind of illustrate all this, let's pretend you are making a new app as a shared inbox app, heavily influenced by Intercom's shared inbox. And this is the mock-up that you have of what you want, the design that you want your inbox to be. So part of the design of the shared inbox is this top nav bar where there are these toggles that are used to select whose admins inbox you're viewing. So when you're switching between one admin's inbox and another's, you know that you'll want to replace all this content here highlighted in yellow. And you'll also know that the URL needs to change along with it. So from inbox slash jess to inbox slash ming. Similarly, within one admin's inbox, if you want to go from one conversation to the next, you know that you'll want all this highlighted in yellow content to be replaced. And you'll want your URL to change from ming slash conversation slash three to ming slash conversation slash two. And so by knowing the interactions that you want your UI to support and what your URLs will look like, make it really clear what controllers you'll need and how you should structure your page from a code point of view. So, you know, this means that you know that you'll want this top nav bar that never moves and just stays there. You'll know that you want this bottom area the area where you're actually rendering what's in each person's inbox. And within that, you know you want this side bar with a list of all the conversations. And you also want this right side panel that lists the individual messages within a conversation. So not only are you forced to think about how you would structure your page beforehand, you're also thinking conceptually about what each part of the page is and how they fit together. You know, kind of like how a designer would think about it as they're designing it. I have a strong belief that design and engineering shouldn't be siloed. And Ember does a really good job of encouraging that. So, you know, I've talked about these three things that you need to learn. Embracing frameworks, navigating the component hierarchy and loving Ember URLs. So what's the best way to learn all of this? Personally, the thing that definitely allowed me to learn Ember the fastest was working on an app from scratch. Now, this isn't always possible. You know, there isn't always this business need for an internal app to be made at all times. But if you can manage it, it's really the best way to go. You know, it's good for kind of the business as well because you don't have this beginner kind of doing crazy things within your main product. And I think, you know, as a beginner it gave me a lot of confidence to, you know, write code and not have to worry that I will break this large production thing that thousands of customers will rely on. And I think that, you know, working on an app from scratch will allow you to see an app the way that Ember intended it. You know, out of the box, uncustomized. If you compare that to more developed apps, you know, which might have things like a lot of custom libraries, deprecated framework practices, idiosyncrasies from having, you know, dozens of developers work on it, a lot of random hacks. You know, it's just a lot easier to learn on something that's simple. So, you know, talking back to that internal app that I started off on, you know, if you compare what that looks like to, you know, it's pretty simple, pretty clean, just a couple of a couple of sections. If you compare that to our main intercom app, you know, just from the outside, the superficial level, it's much more, the intercom app is much more complicated. And if you look at the application routes file of that internal app that I started off on, you can see that it's super short, only like a dozen lines or so. We're not importing anything crazy, very standard methods. Compare that with intercom's application routes file. Super long, doesn't fit on one slide, but you kind of get an idea by looking at the side minimap. You know, we're importing a bunch of different mixins. It's just a lot more complicated. And besides, you know, just simplicity and clarity, I think engineers, especially beginners, can get a lot of value from working on a Greenfield project. You know, the setup work that you have to do to like get an app started, like dealing with package dependencies and stuff can be pretty frustrating, but I think ultimately a necessary part of an engineering education. But kind of balancing that simplicity, I'd also really encourage everyone to build something that people will use. So, find a small, contained, but real need of the business and use that as a starting point. So, I think a lot of beginner tutorials will tell you to, kind of guide you to build something like a to-do list or a blog, but you know, while those do have the benefit of being very simple, I think there's a lot of value in building something for, you know, real users, building an app for real users and not just this hypothetical app that no one will actually use. You know, because, you know, if you want to make things, you want to be a product engineer, I think it's really important to foster product sense right from the beginning. And when I say product sense, I mean things like thinking about how they'll interact with your product, you know, what features you have to have and what features can you cut out, you know, technical versus design trade-offs. Because at the end of the day, you're learning Ember not for the sake of learning it, but as a tool to make something. Thank you. And if you have any questions, feel free to tweet at me or email me.