 Hi, mae arna bobl Chris Game. Felly mae yna i, DMG. Mynd i digwydd i'n gwneud fyddion yng nghymruoladau a'r dd Sidw i mewn gweld iawn i gael eich gyffredinol o'r ein llyfr. Mae'r ddodw i'n gwneud gwybodaeth o'i gael eu dros gyda'r drwg ond nhw'n ddigonio ac i ddim yn arbennig ran hyn. Gatherwch. Mae'n angen i gyflaes pepperau o'r cyffredin. Felly, mae'n holl o'r cyffredin. Mae'r cyffredin yma eich myfyddiadau i colli ochr a chymdeithasio. Mae'n holl o'r hyffredin. Mae'n holl o'ch gyffredin newydd ac mae'n myfyddych mewn o fwylau eu cymdeithio. Mae'n holl o'ch greisio i gyd hyn, ac mae'n hyffredin. Mae'n holl o'r cyffredin, ac mae'n holl i wneud. bwc neu os ydych i'w gŵr i'w rhoi, ac roedd y gallai gwneud ei fod yn ddim yn bwc yn meddwl. Mae'n cael cysylltu. If that there's one take away from this talk today is that this is a example of how to get some of these things working to start with, that you can just pull down and it does work. So you can actually pick through it and I'll go through it exactly what's going on because I think that would really help me to start with. So this is aimed at people just starting out. Rootsmeneinver, because it has to be slightly comical, it's loosely used in the talk. I want to talk about two different examples so the first is to do with nested resources. This is one of those things where you can really see what use cases they were thinking of when they built this felly ei ddweudio'r cynnigau'r cyflawni arall, unrhyw rhai o implemented 아니야e, maen nhw gyda'r cedlaeth cerdd o'r cyflawni arall, ond dyna'r cig ar y ddechrau'r nhw sydd wedi blwrdd o'r ddefnyddau a'r rhywbl dw i ddweudio'r cyfle i gweld, ystafell ddweudio'r cyflawni arall, o'r ddechrau'r cyflawni arall, a'r ddweudiaeth yna i gyrfa ar y camera. Y cwmysgol yw eich tu'r gweld ar y cwmysgol ar hyn. Mae'n amlwg ar y cwmysgol ar y cwmysgol. Ffonslaid. Ffonslaid. Ond. Ie. Felly, mae'n mynd i'r ysgrifennu am rhaid i'r cwmysgol yw'r gwylliant i gyddon ni'n gweld ar y tîm o'r trwm oed yn y gweithio'n ganddwy, felly mae'r ganddw i'r ganddwy o'r ganddwy o'r ganddwy o'r ganddwy. Ond oes i'r rhaid, mae'n gweithio'r ddweud y llwyll yn ddweud hynny. Ac oes i'r ddweud ymarfer, mae'n gweithio'n ardyst mor cyflawni, a'r ardyst yn fawr i ymwylo, ac mae'n gweithio'r album. Mae'n gweithio i'r fawr i ymwylo i'r fawr, ac nid o'n gweithio'r mwylo'n cyflawni ar gyfer ymlawni. Ac mae'n gweithio ar y cyffrediniaeth, mae'n fawr i'r ddweud yma, is it's actually making a load of requests. So this is an Ember CLI app, these are all built in the HTTP mocks that you can use and it's using the kind of rest adaptor, so it's a JSON API structure. So if I refresh that now, we can basically see it go through and make all those calls, so I've put some delays on some of them just so you can see it kind of building up slowly, but you can see it's actually going away and it's fetching that data based on the relationships that exist in the model layer. So, yeah, so I guess if I show you that in code, so we're talking about the roots here that are just artists, it's a resource, a story of artists, artists, and then within that artist and then album, so in here you've got quite a strong convention, which is that you're using the name of the root and then an underscore ID on it. So what that means is that when this goes away and actually executes the root, you don't actually need to declare those, so if you look in here I've got a root for album and artists but not for artists because essentially what it's doing is exactly the same as this line here for the model where it's just doing a find on the store with that album ID, but that's just convention. Like it's just going to do that for you because that's what it's expecting, so yeah, so I guess if I show you the templates that come with that as well, so the other thing that's going on is that when you go say into artists, we've got an artist root, which is a resource, but we're not using the index template, we're using the actual main template. So what that means is that when that's rendered on the screen, it will stay there and then whatever you've got nested inside it will then render inside the outlet, so that allows you to stack that information, to stack the kind of templates to match the URL structure. So you might think that looks a bit mental at the moment in terms of why would you build an app that look like that, but a lot of the things that you perhaps would use later on, say like Ember Fire and stuff like that, use that method of having everything on the DOM, but it orchestrating what's shown to kind of give you a kind of nice user interaction where as you go deeper into the nested roots, you're kind of overlaying a screen and you're building it up and you can drop back through that just by going back. So I guess the interesting stuff here really is that I'm saying each artist in the model for this, so this is the top level of my models. So essentially we've got an artist that's related to albums and that's an async relationship and then that in turn is related to tracks, which is also an async relationship. So what that's meaning is that until I actually request data from that relationship, it's not going to be fetched. So that again is basically showing that when you come through, the only thing that's causing that to get evaluated is the fact that in the template for artist is that I say each album and then request from the model, the album's relationship. And that's going to go through and request each one of those just through Ember Data and then build them on the screen. So all that's downstream of the models is just the adapter, which is pretty much your bog standard rest adapter that's just using the API namespace just because that's what I've got set up on the stubs, what's the default for the stubs. So I guess there's a few interesting things there just if you do like try and build this yourself like it's very specific because you're only relying on that relationship actually fetching the data. If the payload that you've returned isn't in the right format then it won't understand what's going on so there's a discrepancy between how that works with JSON API and say the kind of active model serializers from Rails. So that's mainly around just the formatting so in here the fact that I've got tracks listed there rather than track IDs I think it is for the active model serializers and that will just stop it working so that's one to watch out for. But essentially you can see that going through and really there's such minimal code there all you're doing is just describing the relationship of the models, setting that rest adapter up which is just as simple as specifying where you want it to go. And then the route is doing all the work for you so as you go through it's picking those IDs up and then fetching everything back. So I guess this is kind of illustrated with I think I've seen this diagram banded around quite a bit so to try and explain exactly what's going on. So that's fine for how a normal route is rendered if you like but I guess what I didn't realise to start with is that there's a bit more going on there because that's just you rendering the initial data but as soon as that template is rendered and you try and evaluate that each that lists through the objects really then what's happening is you're actually kind of doing a bit of this as well. So like it's going back and asking the model that's been set on the controller for those relationships and because they're declared as async then that's actually going back to the store the stores then going out over the wire over the adapter to then go and fetch that data back. So yeah so I feel like it's kind of again one of those things where depending on how you use it there's a bit more going on than perhaps it seems initially and initially that is quite a lot to get your head around in the first place. So there's a few more things with that so you might have noticed when I went into here before and navigated all the way through this that we've got some of these relationships when there's nothing happening there's nothing to show yet you get a loading route so that's basically a substrate that's on each one of those routes. Now that kind of seems quite trivial but it actually changes a lot what's happening so if you saw the talk that Aaron did the other week about how that transition objects works and it gets passed through the kind of the various routes that are transitioning. What you're doing by doing this is saying that so you know that some of this information is going to take a long time to return and by doing it it means that you don't lock the screen up so it will start rendering the previous outlets because when you move into that it's effectively evaluating each one of those routes that's specified on the URL so artists then artists with the idea of one album with the idea of one. And if you didn't have any loading routes in that situation it wouldn't render anything until all of them had resolved so by by kind of specifying these loading routes you allow it to kind of partially or to render the screen but no it's going to go back to another state once the data actually arrives. But what that means is that when the route is making the transitions it's not doing what it normally does which is not making the jump to the next part of the URL unless it's happy everything's been satisfied. So that means that you then end up having to handle the you've got like an error sub state as well because that's kind of where you've got to handle that stuff so it's literally going to transition straight away and then just expect the data to come back afterwards. So there's quite a lot going on there just by specifying that. And I guess the other thing I just wanted to show which is a bit contrived and some pre horrible looking code but I think serves a purpose which is in the route for album I've got this horrible before model looking thing. So essentially the transition objects I'm only just beginning to understand I don't think there's a huge amount of docs from what I could find out for it but so I don't think accessing underscore data is a very good thing so I wouldn't recommend doing that but essentially it's quite impressive that actually all the data that you build up as you go through those routes is in that transition object. So as you're going down that I'm able to go and fetch the number of albums that were returned when the artist was requested and the albums returned back and then fetch out the idea the one that's on the route for where I'm going to transition to and then also fetch the idea of that last album back and essentially what that allows me to do is validate before I go and fetch the data whether there is an album that exists for that. So this is a bit contrived but you get the idea that essentially because you've got in here only eight albums awesome as they were if you were to put in here or sorry seven albums awesome as they were if you were to put in album eight in here then essentially what I told it to do is just stop and go back to the nearest route that it can which in this case is to transition back to artists so you can pick one of the albums that is valid. But I guess yeah there's kind of there's a lot going on in there basically that you can you can fetch that information out. And so I guess that's that's kind of cool that's your your kind of crud like a kind of UI if you like that your data is all hierarchical and all quite nested and I guess that's great for writing admin consoles and stuff like that. But what happens when you're trying to do the right thing you're trying to have all your state in the URL but essentially you haven't got one. So the next example I want to show you is a dashboard which essentially is I guess now all three formats is essentially a kind of scenario that I guess is not uncommon to an app but it I didn't really see that it was kind of covered anywhere in the documentation that was up there. So this is correct I think in terms of the fact that you haven't really badly decided on a URL structure. You're basically saying that you've come in and you've logged in and essentially there is no more state to the app other than the fact you're logged in and you're looking at this page. So in this case it's just called dashboard but essentially all the data you're getting back is based on the fact that you've identified yourself by some other means. And so I'm assuming this has just happened from this point in the example but essentially you're going to go away and you're going to need to fetch a load of information based on that user. So in this case we're saying five different services that are all able to return that information. So I guess you know thinking about this it's kind of there's a lot of ways of doing it but but really trying to make it work in a way where it deviates the least amount possible from Ember's standard way of doing it. I.e. what you'd normally expect to happen is that the route would make some kind of request and fetch a model that would then be set on a controller and then you'd have a template that rendered that controller. So essentially the way of approach that here is that you've got so if I show you the diagram of what's going on it might make it easier. So essentially all the route does is set up a load of requests so using the run loop it will just basically schedule those requests to happen at some point. So rather than it resolving in the model hook and blocking the flow it's going to bypass that in the after model I've said it to but essentially it could go in the set up controller as well. But essentially what you're doing is saying off the kind of main thread if you like I want to go away and do this stuff and I know it's going to happen later and that's fine. So the main execution can run through as normal the route evaluates there isn't any model there's no blocking it schedules these things to happen on the run loop. And all they do is say go to the service make this call when the answer comes back set the model on this controller the controller is not connected to the route they're just ones that are created just for the purpose of this. And then the controller that is actually belonging to the route all that does is alias those other controllers and pull the data through that's been set. And so you know this is a bit of a contrived example but what that means the reason I've done it that way in this example is that each of those controllers does serve as a proxy the same way as it would do to the model in the sense that you're doing an amount of aggregation at that point. So you get the data back from the service you need to perform some kind of random maths on it in this case to come up with with just a percentage for each service and that's bespoke to each one. So essentially that's what it's doing at that level and then the controller level is more like you'd expect normally where all it does is just to give you access to the particular things that have been computed from the payload that's been returned. But it seems like this is quite a good fit in the sense that you've got more than you would have normally but essentially at the point like you're not blocking the flow you're rendering the page normally and then you're able to actually get back to normal straight away in the sense you've just got a single template that's asking that controller for information in this case it's using some components to actually draw the information. But if I go through it and show you that so these are from the bottom up I've got a service for each one and essentially all that's doing is essentially just a plain object that's going to be injected into that route and all it's doing is a standard Ajax fix to set the properties on it. So yeah so I guess there's a lot of talk about services actually becoming a proper class of their own and everything I think but like this weirdly or I thought of it weirdly if you do this at the moment. You do get these popping up in the inspector quite nicely in the container as being services so I'm not sure if they're ahead of the curve there or that's just some kind of magic. But yeah so essentially on the route for the dashboard that service is injected along with a load of the others and the after model is essentially just setting up all these things to happen. So services are injected I've just grabbed those into normal bars fetch the controllers and then each one is just in a simple run once to just fetch that service and then when that succeeds it will then set the model on the controller. And then to look at one of those controllers if we just pick the twisted one again. So essentially this is completely controlled but all it's doing is just pulling the data that comes back off those that are just some arbitrary values and then performing some maths on it to produce a number. So that's called utilisation and it's obviously observing the model that comes back. And then in the in the template sorry in the controller for the dashboard all I'm doing is so needing each one of those controllers and aliasing the usage property of each one on it. And then that essentially just gives me the whole thing back then I'm able to assign that to a property on the controller and then from the template you simply just got the component just pulling through that single value. So it seems like it seems like a good pattern so I don't know if anyone else has tried to fix that or anything but but it just seemed like I don't know I've tried it a few different ways and there's all sorts of routes you can go down but that to me seems like the least like offensive in terms of the fact that you're not really digging into the internals at all you've just got more of what you'd expect to have normally. And I guess depending on what what you're actually trying to solve potentially you don't really need you know necessarily those separate controllers you could be setting those as different properties on that individual controller. And I guess a lot of that stuff potentially changing with 2.0 anyway and the kind of attributes being set for multiple data sources and things like that but but yeah it just seemed like a kind of better solution than I'd seen before. So so yeah I guess that's that's really what I wanted to say I guess just that there's there's kind of I think a lot to be said for just reading the docs end to end as much as you might just think you're trying to solve a problem right now. I think that probably applies to all the documentation that if you just read it end to end then it's kind of like a whole story as to what's going on. And I guess that's part of what the guys were saying before about like leaving your expectations at the door is the fact that you're even when you think you're not doing it you are doing it because you're kind of jumping into a point where you're like this seems like a controller problem. And it seems like I should be able to do it with this method or in this area. And that means you're already narrowing your field and not realizing that there's these other things that exist that really if you've read everything then you'll understand where to look but only once you've read everything do you know where to look. So yeah so I guess if that's that's probably the the main thing that I take away from it is that or from this is just that yeah probably don't rush to fix stuff just try and kind of read around what you're trying to do. And I guess if if that's too frustrating because I guess when you start you do just want to see something work straight away then maybe this is useful like this projects on GitHub. So you can pull it and at least check your sanity by the fact that like this is everything plugged together that does work because I guess the other problem is that a lot of the times when you get into the examples. Some of the things are omitted in the sense of trying to make the code samples brief but actually when you're learning again especially if you've jumped into that article partway through it you might not even realize that that has been omitted you just don't put it in the code and then wonder what the hell is going on. So so yeah I guess at least this this is a start and hopefully it will be useful to someone but yeah any questions. You can fetch it just through that. Straight off of it. Cool. You didn't like the way that you had to have a particular data format in your adapter. There's a serializer class. No no no no. Yeah no no no not so much that I didn't know but just I think sometimes the same thing again if you're if you're reading the guides you might read a part of the adapters that tells you about the differences between the two and then not realize when you're reading the next example it's exclusively talking about Jason API and therefore you know it's I guess to me that's subtle in the sense that the because you're because the the the interaction back. To the model is the thing that does the fetch that just breaks and there's nothing obvious going wrong like everything renders there's no error in the in the in the console and there's no no action over the wire so it's not like normally where it makes a request and it fails because it says it can't marshal the payload. It just doesn't realize there's anything to fetch because it's not going through and realizing that's the relationship that it needs to evaluate so yeah I guess it was just a bit of a gotcha. It's probably more when you're doing things like this that are just knock ups because most of the time you're going to be either one or the other or you're intimately aware of what your payload should look like but yeah I just thought things like that it's kind of. You know it's really clever what it's doing but you have to kind of realize that there's a lot going on under the covers and so like it can just break at some point. We tend to use JSON API as the standard so our serialized is transformed and we often serve it into JSON API. Right. And then just use the standard adaptive processing. Nice okay yeah yeah yeah yeah definitely no one's going to ask me what happens when the resources disappear or why aren't I using resources that's good. So like I know there because they're going to get they're going to go completely as I understand it and so I did look at this because you can nest roots now obviously but that seems to work quite well. So I did try that briefly but the so the stuff I've got doing this basically is a lot older than this so I brought it up to date to a point but yeah I just found when you so when you nest roots it's slightly different in the sense that when you're specifying the links. So where you've got in here so like you would link to album.id that if the root if they were nested roots rather nested resources that would be artist.album.id and then it seemed like it wasn't playing ball with the standard outlets but I'm not sure if that's because you now need to name the outlets as well and like they have to be named by default I don't know. Hg a quick show of hands who is aware of the difference between a resource and a root in a root as Karen stands. So a resource you can think of it as kind of wasting that route up to the top level so you can always refer to it by just its name on its own rather than its name nested down when in all of the roots of it. Yeah yeah because I guess that was the other thing I didn't say actually that in the in the router so it might look a bit mental on the URLs but I deliberately mounted those diagrams at the same level. So that's just to illustrate that although you've got that nested hierarchy if you want something attached to it that a refresh or a direct link to isn't going to evaluate you can still do that because I think the root is just evaluating what's at the top level first. So essentially so I guess to just to show you that if if I went to if I went to the diagram level well so I guess so if I go all the way through this navigation and I'm essentially at the same level that that diagram is going to be at and I click it I move in and you've got the full URL. But if I were to refresh that you shouldn't see any of those network requests go out it's just going to go straight to that route so you can mount stuff that looks like it's a nested level but actually doesn't require all the work to transition through the roots to get there so I guess that's quite powerful as well if you've got stuff that's you know it makes sense from a from a information architecture point of view that it lives at that level it's just that you don't actually need to go and fetch all the data to pull it back. But yeah.