Video details

Scalable Enterprise Angular Applications | Konstantin Dinev & Damyan Petev


Konstantin Dinev & Damyan Petev

This half-day workshop will offer developers a hands-on exercise on how to approach an Enterprise application in terms of: – Structure of the application – Creating Angular application that consumes the data and scalable UI that displays the data to the end-user
ng-conf is the premier global conference for the Angular JavaScript framework, offering both in-person and online events throughout the year. Focused on delivering the highest quality training, ng-conf is where careers are made.


I just posted the link for the GitHub repository in the chat, and it's not something that you have to clone right now, it's just a set of predefined so sort of steps that you can copy and paste out of in the read me and some snippets that we've prepared so we can get this going a lot faster than we normally would. And by the way, you will notice in the repository there isn't actually a result, meaning there is no application to clone because we didn't want to shortcut the whole experience of building this whole thing hands on and of course, the experience of running into issues. You don't see the link? Oh, yeah, I'm sorry. I think it zoom posted still panelist's by default. Apologies. Let me change that on my end as well. Yeah. If you want to post to everyone. Yeah. OK. So I'm going to get started now no, I'm just going to go ahead and share my screen so everyone can see this is the repository that I linked. And as you can tell, we've already outlined some of the basic steps that everyone needs to needs to have no choice, obviously. And then a global installation of Engler's Seelie, which this is income for, I assume you'll agree to do. If not, then. Quickly, you use to use this command and get yourself a copy and then what we're going to start with is actually we're not going to start from a barebones, angular project. We're going to start with a project that's pre reconfigured for our Nightwish for angular product. And it has some additional benefits as well that we're going to discover right now. So what we need to do that is to get a global installation of our schematics, which is step three in the repository. So I'm going to go. I already have it, but I'm going to go ahead and run that anyways. Um, can I make this go away? What do you need to make go away? Oh, I guess you don't see it. That's my that's my panel. It's the Zoome panel on top, but I guess it's not visible to everyone. OK, yeah, we're just seeing your screen and over on the side, so I'll deal with it. I suppose I just moved all the way, right. Yeah. And even if you already looked at the repository, since I believe those were in the links before, just go ahead and grab the latest version because we've released the data even today. So. Yeah. This should give you something in the lines of anger, toys, angular schematics, eleven seven point seven or one. And I guess this is the point where I ask everyone to just raise hands and let us know that they're ready. All right, I hope I'm saying this name correctly, Marcey saying that in the view option since Zoom, you can hide the green bar cruel it's find it doesn't it doesn't interfere all that much. I got a comment. All right. Hands have been raised and then they're lowering. Right, perfect. OK. At that point, I would assume that we're good to go. All right. So once we have those schematics installed, we can actually use those as a collection for a Injinoo, which is exactly what I'm going to do. So start with Injinoo, just like you normally would. But this time don't add anything else. Just provide the collection argument. And say that the collection is just going to go and copy paste stuff because I am very lazy. It's what we do, we're supposed to be lazy so we can figure out ways to optimize things right for everyone attending. You can copy paste from the read mean the repository that we're linked. Oh, yeah. Yeah, of course. Yeah, this has. At the rep at the set up stage, it has all of the comments that we're going to be running and some of the comments that we're going to be running afterwards as well. Constantine laid it out all in the very detail. Yeah, just FYI, there is a lot of things that are not hundred meters high level, and so you still have to keep up with us and raise your hands when you're done so that you don't fall behind. OK, I'm going to go ahead and run that. What this is going to do is pick up our schematics and run some prompts for us, so the first thing it's going to ask is probably expected is pick a name for the project. I'm going to go it and come. Workshop 20 in. Because when. And then something interesting happens, see, we have a bunch of templates for for a new project that you can build off of. We have a very basic empty project that's pretty much a slightly upgraded version of the blank engineer project you get with routing enabled in SAS. We also have a project that's pre set up with some navigation and layout. And then what we also have is a further update that also brings some built-In navigation services. And we're going to go and pick that one because it's the most blinkered out project that we want to show off. It doesn't only have navigation, but also has some pre-built authentication snippets. Exactly. And so I'm going to show I'm going to show you guys around the project in a second once we get it up and running. So, OK, we're going to go and that project template and then it's going to ask us what team do we want to use for a project? We can use the default Nightwish for Engelhard team, which I'm actually going to show off, I think is enough to show off. Right. Maybe not this one. Just choose custom. I'm going to choose custom because I will use it further on to customize a team even more, and then it says the project is done and we're going to go hit complete and run. Something that we should note. Right-Winger is available. Is DeWall is it do moistens Konstantine? Yes, it's a non dual license model. And so for this workshop, we're going to run it without the license because we don't expect that the attendees have acquired a license for our product. But the product is fully functional without the license as well. That was like a bit of a visual glitch, let's call it this way with the trial watermark. You're going to see it in a bit. Yeah. Yeah. So we're going to skip for that for now. And the port is for 20, as per usual, and then it's going to go ahead and spew out a whole bunch of files and start installing. Has everyone been following along so far? Anyone falling behind. Oh, good. OK. Which team did you choose, default or. Custom and you got that, ah, did you just install the angular schematics that we have or are you running with the version that you've previously installed? Fresh information, so that is Superdrug, yeah, because there is a dock manager somewhere in there in the schematics. But it's not supposed to air out, right? Definitely not like that. I'll try over here, please do, and let us know what's going on. Oh, so Maurier's. Oh, boy, that. Angular kid. And this is in a fresh project, right? Yeah, it's even angular. It's like the built version is 11, so it's not even old for a decade. If the current version of that gift brings out an outdated cardioversion version, that is super odd. It is actually a couple more errors, people, OK, then they're all different, so we have one collection. Triangular schematics cannot be resolved. And that that should be because of a missing global install. Yes, yeah, so you have to install globally on your schematics in the read me. This is why I'm going to explain that a little more a little more in detail. Angular Seelie results come out either within the project or globally. And since we're running continue, there is no project, so the only way that can resolve is global install. Yeah, if you if you if you run it with. If you manage to install it locally, then it might, although that is a really odd way to work, the workaround that I remember at some point and Angular Seelie didn't resolve those for me as well, maybe try updating your angular Scilly version as well. Oh yeah. Old English version would cost samaris. They've had errors in the past, but I haven't seen them for like at least two major versions doing that to. All you had the project from the read me, yeah, just just start with a blank repository. Oh, yeah, OK. I guess I guess that's because I failed to mention we're just starting in the blank blank folder. We're not running inside the project at all. I'm sorry if that got anyone confused. Yeah, we're creating an entirely new project. Like I said, we don't you don't need to download this repository. It's just here for the reading and some snippets that we're going to include in a little bit. So dominant. And I already have the app. Can we get a raise of hands of people who still don't have them have the project running? OK, but I'm almost there. OK, that's good. OK, looks like we have about 80 percent success rate. Seven looks good. All right, we haven't done anything too complicated as will be at. Yeah, but both both the client and the schematics need to be installed globally for that to work in the blank folder. Because it could have already installed packages, Syngenta is just going to freak out and saying there's a lot of code being generated. Oh yeah, there is a ton of code being generated for this. But then again, if if if we're going to do like a complicated application, it's not going to go to waste. Trust me, it seems to be working now. OK, good. Let me just check again how many hands that we have, five hands, five hands. Nice. I guess I can start showing around what we have. Yeah, yeah, you can. You can walk through the project structure while people still get it set up. I really don't want to kill my running application right now. Yeah, I'm I'm going to kill it in a second, though, because we're going to be doing some more stuff to it. Should I just do the performance measurement right now? So I'm the Damián walk us through the through the project structure first and then do the performance. You can do it from another. Come out. Just open it from from. Oh, just open it separately. All right. You should not exist buddy. I do. Left. All right. So what we got generated at this point, it should seem very familiar, like it's basically an upgraded standard, angular Seelie project. That's what we're doing. So angular Seelie still included in the project as well as our schematics so we can run all of the commands from here on out. And any command you expect will run just fine. It's an angular 11 project and what you have for the most part is very standard, except again, the component is reconfigured as as you already sew up up until now, we have a layout setup which has a navigation door which shows us our navigation views. And we also have an obligation bar on top which hosts the login. And we also have another outlet set up somewhere else, content. We also have one home component that doesn't really do much of much of anything besides being a welcome. And what we also have set up is routing, of course. And the big part of this of this project, besides being ready for all the ignite triangular components, and we're going to see how easy it is to install those in the second row, more like a few minutes at least. But the big thing here we have oh, in the routing module, we also have some uncoated here. So we have a global air handler and we also have a page not found component. So a little bit of setup for you guys there. And then the big part, we have an entire authentication module, which is right here, there is a button to log on inside the now bar and it's already pre configured with a local login. So an email plus password. Then it can also go ahead and say, like, I want to create a new account with first name, email, password. I think it's very basic, but it's supposed to be a jumping off point. So basically, you have a full full on authentication service that's. Configured to work with a back end, so the current plugin methods that go in are trying to call an API for log in, an API for register and an interesting part of an API for an external login. So we have something else hiding in here. What we have are a bunch of providers. And we have a basic provider interface which goes into a log in, log out and gets user info, and the project is already configured with a basic open ID provider. It's using a fairly popular library called Angular all over to see, which is open iConnect Point. And it's one of the one of the certified open Edek Connect Libraries for England typescript. And we have based on that, there is a basic provider which you can use for anything like Constanten uses it for Twitch. Right. And we have based on that, we have a Google login provider and we also have a Microsoft account provider and there is a Facebook. Has Dekay included in this project? Because Facebook doesn't still, I believe, implement open ideas, but they have their own SDK and this is also reconfigured. But the main point of this is this is all tucked away in an authentication folder in your project, and it's all just pretty much ready to be used. So, for example, what we deliver in your application module, you should be able to see this is within the constructor. There is a link to some documentation we have for our authentication project. And our service that comes with the project has some registration points for different providers. So basically, all you have to do to get some social login is to grab an account, your client key from your Google developer portal, for example. And just uncommented this line. I'm not going to enter a IT right now because I would be silly. But what you're going to see is basically this button pops up and if I uncommented out the Facebook thing. It's going to pop up with all the science and they all do work, although that's very invalid client, so I'm not going to go with that. But it's just something to know, like. It's extremely easy, like uncommented one, one plug in the key and you're ready to go. All right. At this point. We've seen what we have. And I should show you what we're going to try to improve in the future. So I'm going to open up some deftness. And I'm going to jump to Lighthouse, which is the performance evaluation tool built into chromium Steptoe's. And I'm going to run a quick report. And I mean, why do you do this? Can you tell us? All right, yeah, sure. So what we're trying to establish is some measurement within our application, of course. Keep in mind, guys, this is currently running a development on the server, so it's not optimized in any way. So the performance measurements we get here are not going to be extra meaningful, but they are somewhat meaningful. So what we are looking for is to evaluate how quickly our application performs and most importantly, to evaluate how quickly it loads. And there are multiple measurements for loading performance. It's not just how quickly you're going to you're going to transfer your files over. So that's one thing. It's also how quickly is the user going to see something and how quickly is he able to interact with your application? And what we're looking for right now, what we're looking at is the first content grouping paint. Which basically shows you the first content that is presented to the user and I don't know how visible this is. I guess if I zoom in. And we can see the first three snapshots here are blank screen. Yeah, so our first content to paint is not that bad in all honesty, because this reloaded really click on my local machine. But there is like a certain period when you load the application where the user sees just a blank page while angular boot the components renders components around, they style themselves for their size and actually appear to us right. And that's something that we can improve. And that's actually something that Angler's team provides as tools for us, and it's done through server side rendering. So mean we have on the one hand raised still OK, but I'm not sure if there's still a problem or the person just forgot that they raised their hand. I don't know how to mention in this chat. Does that work? No, I think I'm I'm trying that it doesn't suggest, like, you know, we use teams instead of Zoom and we're used to some, you know, some some stuff from teams. Anyway, in the interest of time, maybe maybe we should keep going. I'm just going to go ahead and see this preview. And keep it tucked away now, OK? And what are we going next, unless unless the Democrats are really evil with us today, we're going to see an improvement once we do the next step. OK, so at this point, I'm going to cut the execution on this one and. If you noticed, we just created the project, so we're still on the folder outside of it. So just just to avoid confusion, you should go to your. Project director, before we execute the next step. Now, let's just hope that encode directly I have it in code, all right, but you already know that although I appear to have changed something and I don't know what you commented about the. Oh, yeah. Plugins. Yeah. Oh, yeah, that's fine. All right. I have no hands raised, so that's good. OK, I guess we can do that in this code as well. Fair enough. All right. So what we're looking to do is add one of angular Universal's tools for service side rendering. And we're going to use the express engine today since it's based on no just server. And it's really easy for us to go ahead and configure additionally, without requiring you guys to go into, for example, to have an ASP.NET core version of that engine, but that would require Visual Studio and Epicor and stuff like that. So this is just the shortcut. Easier way. Plus, we have over the snippets prepared and I'm not changing that right now. Yeah. So what what we're going to do is go for Angad. And I'm thinking those sort of my history because I can, but for the rest of you, Angad at NBC Universal, which is English Universal Express engine in those packages come in like wild card dash engine flavors. So that's about the same package scope. You can find ASP.NET core engine and I think they have a few others. Yeah, and you can you can still copy paste this from the read me just halfway I yeah. And yeah, go ahead and add it and in a while you do this, please. If if you're not familiar with server side rendering as a concept or with server side rendering in angular, please raise your hand and maybe I can expand on this while this is being installed. All right, we actually have quite a few hands. OK, so just all right, so yeah, explain away. Absolutely. So because Angular is a is a single page application framework. We had a lot of hands go down. Right. So when when your application is being delivered to the client, it's basically an approved only and there isn't a whole lot of content in it, you know, rendered. And that's the point where angular, you know, then your main applications scripts get downloaded and the application starts bootstrapping. Right. And so what? Yeah, I have your visual right here. What gets delivered to the client is exactly as what you're seeing is is exactly what the client gets delivered before the application starts bootstrapping. The server side rendering is a way for you to deliver more content to the application by invoking the angular compiler on the server and actually delivering parts or even the whole HTML for the components that are going to get rendered that certain routes that are being requested by the server. Now, why is this important? Like any real world application? Actually, in order to be scrollable by a search engine crullers and so on and so forth, it should deliver some content like Google recently updated search engine so it can evaluate ECMAScript version higher than five, but be before like the I don't know when that happened, but it was I think sometime at the end of last year before that, if you have an application running ECMAScript 2015, for example, it wouldn't get evaluated but by the crawler. But ideally, what you want to deliver some content to your users, not only because of search engine crawlers, but also because that actually enables better performance or better perceived performance, we should say, for your application to your end users, because they're seeing pixels rendered on the screen even before the application starts bootstrapping. So we're we're adding server side rendering to this application one, because you really want to do that for your production level applications. And two, because we're actually going to kill two birds with one stone. And this workshop by reusing the server that gets generated, the express server that gets generated by the angular CLI and adding some API and points to it so that we don't have to create a separate API project for this workshop and we to see that everything finished installing. So. Yeah. Oh yeah. Can I expand a little bit. Go ahead then. Oh yeah. Because like you said, the perceived performance is king in terms of actual performance. So what the users are seeing is like a pre rendered shell of the components that are about to be. So the server side rendering renders the components and dumps them afterwards very rudely and then just grabs the demo and sends it to the client. And then what they're seeing is how the application is about to look like in advance. But the entire angular application and the background is still bootstrapping and hydrating back those components in pretty much the same time. The difference is just the visual. Right. And the visual was actually very key. The Google search bot might be able to run the angular application these days, but there are other search blocks that are actually just as important, especially for marketing, maybe even more important. So, for example, Twitter, Facebook or any social media willing, you share a link there, they will go ahead and grow the link that you've shared and try to pick up a preview. Right. And that's very important in terms of marketing to be able to control and server side rendering gives you control over that. Why don't you run it so that everyone does this with us and at the same time, like because this is an enterprise level workshop, we want to say server side rendering may not seem important if you're doing, let's say, a back office application or an internal application that's only going to be consumed inside your organization. But because, like, you're never exposing this and it's not dimin, go ahead and run it. Right. All right. All right. Hold on, let me let me just show the run. All right, so to run this, because what happened when Angela when the universal package installed, it created a whole bunch of stuff for us. So it created new commands in our pockets to Jason Run. It does have matching configurations and angular jassam. We have a new server module that surprise, surprise bootstraps, the same component as our usual module. And then we also have a server test, which is basically our express server handling API. And we're going to go look into that in a second. But what what we want to do is when one of our new commands, which is run dev SSR. Which is for server side rendering. And while this is being executed at the airport back office applications, it's still important because of what that means, that the perceived performance of the application, and especially when you have like views that are more data heavy, more domme heavy dose, usually take a little bit longer to initialize, especially if there is a lot of service calls. And so you want to have more pixels initially in order to make this incremental build up inside your application instead of having Wide-screen going directly to a hydrated view or a loading screen for that matter. So this thing happened. It's not it's not as if we didn't expect this, but we're just going to go ahead and show it. So like like I showed you a few minutes ago, we have our very own Facebook provider, which uses the Facebook SDK. And as you saw, it was running just fine up until now. But what happened? So the server configuration runs off off of its own server config. So we're going to know when it's going to go look into what's happening there. All right. So there's a new TEUs config, that server, Jason, in our project. Right. And then it has types. And for the types that are used to compile time and has just node, oddly enough, our application was very insistently including Facebook says type's so it can compile. But this did not get carried over, which is something we might actually inquire with the England team with potentially like please carry that over for us. But to make that error, go away and have our application compile and run. Normally what you're going to do is grab those Facebook SDK types and just add them to the server config. And that should solve our issues. And this is probably the time for you to let us know whether you are catching up with what Damián is doing. If you're still not up to this point or something is breaking ering, can you can you raise your hand? We have Jeffrey raising a hand, but I think it was raising your hand for the server side rendering. And it's gone now. Now. All righty, well, this didn't an out so far, so my prediction is it's going to be running probably. So what's happening is actually a bit more complicated, since this runs our normal angular room and then it does an additional server build around afterwards, it's actually producing two different outputs, one to render on the server and one to deliver on the client. So what we should be seeing right now is our application just working as per usual. Right. Right. Let's see if Lighthouse will cooperate with us today. More importantly, the patent I can guarantee the patent is going to work, but anything else is up for discussion. All right, mode, pretty pleased Lighthouse. All right. Well, it does show you better results, it is better for some for some reason, the White House just figured out that we don't have robots, robots, which we didn't have before as well. But it didn't complain before. But our performance rating has has been bumped up a little bit from thirty three to forty three. And keep in mind, again, this is all running off of heavily optimized built like a def built. So it's not going to be pretty, but I don't know if this is visible. All of the frames captured while running the report, all of them have something visible. Yeah, and keep in mind, we didn't do a whole lot, but just executed an injured command and we actually bumped up the performance index. Yeah, that avoid enormous network payloads, endeavour. You're going to get that message regardless even. Yeah. There there is no avoiding that with Engler's that builds. It's a little bit atrocious, but it is what it is. Yeah. Well after that we have to debug somehow, right. Oh yeah. The source maps on those files are heavy like. I'm really happy. All right, so at this point, we should probably run a release built so that we show the difference, but let's keep going for now because. Oh yeah. Yeah. Oh, yeah. And in your package, Jason, there are multiple commands. You actually have a new built SSR command, which is going to do that, and then you have a serve as a starter, which you can do afterwards. All right. So I'm going to go. Yeah, four, so that's the error that you need to include the Facebook, says Dekay, typing into your config server Jason. So the typing are already included in the root level config op. Jason, just copy the type and also add it to the server. Yeah. Yeah. There's bad blood right here. In the DNG ad for the server side rendering, it just adds the new files I have, oh, you have already done that and you're still getting in there. Oh, in the browser, did you hold on in your app module? Did you leave the Facebook authentication uncommented? Your comment about. We're not going to get get this set up today. Because, you know, we can actually run the whole workshop on setting up the authentication providers, but, you know, that's that's not the goal that we have to do. Getting a Facebook developer these days is actually like an experience on its own. Oh, yeah. And that's another thing. If you have the server running and you make changes at some point, it may actually, you know, give and I don't think so, actually. I don't think it actually refreshes when you make changes to TEUs config files yet. So. So just stop and none of Dangler builds, do you know? Yeah. All right. At this point, I am just going to commit our awesome performance improvement, even though it wasn't much. It is. You say it wasn't much, but, you know, I just want to add one thing and you get a boost. Thirty three to four to three. What what's that in percentages and in three. Yeah, it's not bad. Yeah. All right, OK, at this point, we should grab our snippets, so if I can turn your attention to the GitHub repository. You're going to find a code folder with a snippet file, so those are pre reconfigured snippets for obvious code, which I love dearly, and I am going to abuse the hell out of those since we hate typing real time. Right. Right. So we're just going to take a lot of a lot of time that's going to take an endless amount of time to get everything up and running, which is no bueno. So what you want to do is go control shift and P and viscose code to bring up the commands or some command shift and P on Macs and type snippets or snip out should be enough and you should see configure user snippets option. Everyone following up. When you select the configure user snippets option, there's a new global snippets which we don't care for and what we are interested in, new snippets for the project. Yeah, OK, I went to see the chap that was a mistake. All right, so we're going for new snippets for the project and we just have to pick a name. The name is of no consequence at all. I just go with workshops. And so I've been naming those for a while now like that while doing test runs. But the name is not of importance and as long as it's within the project. So what this will do is actually create a new file and the same folder structure under the previous code and some file named however you like with DOT code snippet extension, which is the important bit. And here is a lot of documentation, descriptions, how you can enter snippets. What we're going to do is use the ones that I've already done so from the repository, just grab the raw file out of GitHub and copy paste it within your project. And safe. That's it. So, again, the wrong file from GitHub. And just take the entirety of the content and copy and paste it in your news snippets file, and you should see something like this with a whole bunch of templates ready for us to enjoy. All right. A plane asks you to repeat, oh, OK, is not an obvious code. Oh, that's going to be really hard to replicate without this coat, because those snippets are Vaskov specific. I'm going to repeat. All right, so command shift and P or control shift in P inside this code, you're looking for snip and it should give you configure user snippets. And under that, you have a new snippet for file for the project you picked up and name it however you like, and it's going to give you a new file. And within that file, you copy and paste the contents over from the GitHub repo, I'm going to put a link just in case. Yeah, you can you can put a direct link to the file. It's going to put a link to the raw content. Oh, even better. Yeah. Yeah, here it is. Come command should be Olmec, thank you. Mm hmm. OK. There is no sense anymore. By the way, slavery is not on the US code. I was going to say we can push some code to the repository so you can copy paste from there. Damien, do you want me to do that? While you explain, sure. OK. All right. Well, at that point, we're going to go ahead and run one additional command in the terminal before we start using the snippets for some code, so we've decided that we're going to do a very basic resemblance of back in DPI and we're going to build that off of some north window data service. So we just have like a basic amount of data to work with. And since we're going to be making the request and I like the API, which is not available on Noad, we're going to install one more package in our project and it's actually available as a copy paste command in the region as well. I believe what we are looking for is to install note fetch. And I'm going to go ahead and run that. Excellent. This is a fresh, fresh project, and it's already like running to their abilities. That is and we're on on least Liste latest package of versions. For most, everything is like 11 released last week or yesterday, something that is just the NPM Eco-System for you. It's all right. I am willing to bet most of those are Web back dependancy somewhere in the death chain, which is not really affecting our application all that much. So that should be good. All right. Did everyone install? Not fetch. And it was still not there yet because we're jumping to The Servatius file to have a look see. Damien, what are we going to do in The Servatius? We're going to be adding some additional API to what it already has because it has some. So this is The Servatius file, that Angler Universal delivered for us. And it's an express back end, if anyone's familiar with expression. Yes, this is going to look very, very familiar. The. So what we have pre set up by the angular universal. Package is a single gift request for something, dot something or files with extensions that goes to a static server. So those are all our assets, like images and Cyesis files and something, stuff like that. And then we have a general route that is just the wild card and it goes to render through the universal engine and you can see the dust providers and stuff like that. So this is what actually renders our components are the back end. And what we want to do is sort of use this express engine to add some data API to to our application. So what we're gonna do is go ahead and not out of the region just before the generic get the consumer's every request ever. So as long as we're working with data that's from Northman orders, I'm just going to say that this is the orders region and I'm also going to end it. And we're going to pull up our first snippet, which should be orders data. As long as the second you save that snippet files that stupid file, every snippet inside becomes instantly available in code. Just way, if this is not showing up, then something's wrong with your snippet files. So we're going to go ahead and take the orders data. So what if for some reason you don't see the snippet can raise your hand? Yeah. All right. So this is nothing too complicated. We're using our favorite Noad API and just grabbing a Northlands data service with the orders. And I'm actually going to go ahead and show you guys what it has inside. So as per your data format, it's very common to have like Deora returned inside of an object because they usually deliver some additional metadata properties. And then the value that we're actually interested in or the actual array of records for the orders is in a separate property just that way, because that's going to be important in a little bit. So that's why we have a store variable that's basically so we don't spam the preview all day to service all the time, so we cash in that response and as long as we have it, we're going to use it. And plus, that service is Read-Only, so we wouldn't be able to perform current operations. So adding, deleting, updating stuff within the service. So we're going to do it on our cached store or if you want if you want to imagine it like that, that's our in-memory database. Or and keep in mind, like your API being inside your server side code and the application is probably not the best practice, but your server can be a proxy to another API that you have. And this is exactly what we're showing in this case. If it's a proxy, you probably want to do some server side caching on this end as well. And that's why we created a story in a cache. But Damond Wise, why is disorder not available? Because we haven't defined it. Of course. Do we have that in the GitHub repo is a snippet. We do not. All right. All right. So we need an order from as a model. So that would be an interface. So Engie. And we're going to generate that, of course, generate energy. I it's right here in the corner, guys, and the bottom bottom. Right. And we're going to go and call it inside the models folder and call it an order. So models slash order. We go ahead and run that, or it's it's all like you can just create the folder in the file. It's not that far off on the stoop, but still. All right, and now we should be able to import that model inside our Servatius. And you also have a snippet for that. I know, I know I'm going there and of course, we want to describe that data and we have a snippet for that as well. We have a model snippet that small dash orders and that should expand to almost full description of what the old data service will give you. But we're not going to deal with too many of the other properties. So that should be enough for now. By the way, I was wondering whether my cats are going to get interested in this workshop. Oh, they just did. Right, right. OK, so I'm hoping that everyone's all caught up, so at this point, we have some function that cashes some data and we have a model describing the data. And now it's time to write up a little bit of rest API methods for us. And as you expect, we have snippets for that as well, because what you're looking for as a trigger for those snippets for now are get dash delete, which should show up a server, API, forget and delete, since they're pretty similar in terms of signature. And what and that will expand to some options that you can tap through so you can select between the two methods we're doing. Let's start with get, for example, so we're going to do to get method, then you can tap to the next stop on the snippet. And that's the result. We're going to return for get we're going to return, Jason. So this is fine. And for the actual returning thing, it's the data which is also fine. And the last stop stop should send you right here in the argument behind orders, which we don't need since those are all of the orders. So we're going to delete that one. Oh, good. Did everyone get that because that was just the get method and it's done. This is it. All right, so what do we do next? Let's do another guest method, but this time with the actual API for, like getting a single record since, why not? So, again, we're going to get and the rest of those are the same. Except this time we're going to rename the data to an order and we're going to leave the parameter up on top. But. Stay right there. So what do we need? We need our aid parameter, which is going to come up. We'll have to pass it since everything Express gives you the string. But we're going to grab it from the request. Harrumphs Berardi. And requires a base of 10. And if I can type Consed, we're going to go ahead and look for order, which is in data, the value, again, like we've seen in the old data format, the value is the actual rate that we're looking for. And we're going to go ahead and find inside that array and we're going to be looking for something. That has an order I.D. that's equal to the ID from the get request. And if you're really thorough, we can go ahead and actually check if such order exists. So if there is no order, it would actually return. If we're forced out of. Take Constantine, yeah. Oh, that's fine. Yeah, I was wondering if if I should have put an explicit return on those, but they should still work just fine as long as they are. OK, so we have ways to get data. How about a way to add data so. Post again, post and put there very similar in terms of signatures of those share a snippet as well. So Post Dush put is the snippet you're looking for the post daywear is fine, the status code for post since its creation should be to one. So that's it should be created. Is anyone falling behind? Let me know if I'm going to fast. All right, so. For the order, we have a little bit of a difference, so we have an additional handler attached for Express to give us a Jassam, otherwise the body would wouldn't actually contain anything. But once we have the adjacent parts of the body, the body would be the actual order that's submitted to be added. So I'm actually going to rename this to. No, it's fine, it's fine as an order. What do we need for the order, so it's a new it's a new order, so. It would have to, hmm. I was wondering what's happening. I need to type that out. All right, so we're going to give it some random new ID. In this case, I'm lazy, so blank plus one. Obviously, this would be something your database or something else would give you, not something you generate on the hand. But we're just emulating an actual API at this point. And to actually add it, we're going to go ahead. And push, it's not pop. Push it to our data. And if you want to be really fancy about it. We're also going to return it with the status creation. So API that sent the updated order can get it right back up. With the updated daily. Constantine, is anything interesting happening in Egypt yet we have Chelsea get an error on trying to add the server methods. I'm trying to figure out why. OK, I'm going to soldier on for now and see how that's going, keep going. I'm going to try to determine what's happening. All right. So that's yeah, I'm going. Sorry. You can you can reply directly, I think. All right. So we have get data and data. Let's update data. So that would be a put method. So this time again, post put snippet, this time go and put the order up. Submitted with our request body is actually now an updated order that we're supposed to handle. And I can't type anymore, and for the update, it's usually going to be a two hundred or two or four. In terms of status. So do you find the order that we're supposed to update, we're going to go ahead and poke into our data and of course, find. Not filter find. The order, the order with an I.D. that's identical. I really should have put that. Typing in the snippet. And again, if such order doesn't exist, this is where you would usually since bye bye rest API definitions put is also supposed to be able to create. Besides updating, this is where you would be creating a new instance set out to get to data and so you would be returning until one, but we're not going to be using that API for those purposes. So I'm just going to return. A status of four or four. And should such order exists, I'm going to go slightly lazy again and just. Assigned to order, we just found an assignment, the updated order, so all the others will be updated. And we're getting close now. We have one last method so we can have data, we can get data, we can update data, and now we just need to delete. So the get delete snippet is our next target and delete this time. And since delete doesn't really return data. Go ahead with the status and tool for no content. And we're actually going to keep the idea this time and quite pleasingly go back to our get with idea and grab that one in and bring it down. So what we're looking for is for the index of the item to delete, so. We're going to go with findin because this time very similar to what we've been doing so far. And find something with order I.D. that matches what we sent. If such a thing doesn't exist. Should I go type of undefined or just cause undefined? Both should work just fine for causus. So if we're trying to delete something that doesn't exist, obviously for four. Alternatively. We're going to splice. Not item straight out of the datasource. So from that index, I'm going to remove one item. And go ahead with two or four. And that should be our. Order zappy, fairly done in functional. Well, maybe let's start out. Sure, I'm in the browser so I can through the test too many of those. Let's say you give me that we should have API orders and my browser remembers that because I've already had it running before. Oh, body. Oh, that's rough. Hello? Oh. Really did it? Did I not import fetch? I didn't. Oh, boy. And we installed Node Thach for that very reason. This is this is also really disturbing because it's picking up the browser API for fetch and it's going like, yeah, sure, this works. Except we're on the news. It doesn't accept. It doesn't. And we were supposed to import that. So again, we've missed that totally. But go ahead and import fetch from node fetch. A duck has a very good point that the index will be negative one if not found. It's not going to be defined. True that. Very true, says if you've been doing JavaScript for 10 years. And maybe we get the response now. Thank you. So it's no surprise, basically the same day as the day the service provides. So we just cashed it and proceeded. But hey. We can do stuff with this now. So I'm going to go ahead. And commit this one in. Should I ask for hands being hands to raise? How are you guys doing? If you can follow up, I go back to the method. OK, hold on, I can do that. There is a snippet for you, it's. The snippet is get dash, delete, that will expand. Yeah, just he wrote the body because so, yeah. Two tips, please go away. You're so helpful, but not always. I love how it never gets dark when you're in. Yeah, I know. All right, it's actually pitch black outside, but yeah, I see that there is no other HANSBURY, so maybe let's let's add some UI to consumers there and to display it in the application. Yup, although we have a few more editions to go before that, but, hey, we're getting there. Oh, you mean we need a. Service on our own, right, and in the Clean Side app. So, yeah, we've set up some data for from the back end and now we need the client application to consume that. So we're going to go ahead and throw a service for that as well. So that would be just straight up generated through the angular Seelie so and generate s stands for service and we're going to go and services folder and call the service orders or just order. Orders. I like it better. Should be orders because it has endpoints for orders. Yep. This should give you a new folder inside your project called Services and a new service code order service. And what we need to bring in, and this is an HTP client. So. We're going to go ahead and inject the variable named HTP and type, it is HTP client. And if Angela is so kind, it would actually all to import as well. Thank you. Export fetch was one pound not to fetch. Oh, if you're exporting it as as an alias, like a wild card, something that's not going to work since it's a default export on their end, like a ECMAScript module, the fourth export. So it should be import fetch directly from Nuthatch. All right, so currently. Yeah, and one additional thing we should do is in our environment. You have environment files for development and production. Always a good idea to put your service and point that you consume in some sort of some sort of configuration, so I'm going to call this. He orders and point and. It's HTP localhost for 20, slash JPI slash order, so I could have copied that from the browser. But it's fine. Because we're going to use that in a little bit. OK, so we have a service, let's add some methods that consume the backend API. Again, we have snippets for this because we're not cruel. And it's actually a multi selection snippet, so we're going to use it for all methods. It's called service dash method. Like this, and it should expand to something that will do all the work for us, so. We're going to go ahead and create like the first Gethard. So this is gipped and then you tap through and of course, this is also get. And this will actually return on orders array, since we're going to take the entirety of this. And we're going to skip a parameter for now. I was wondering, though, where you're going to remember this actually doesn't return on orders, Harry. Did it not? Think about it. Oh, since it's the variable. No, no, no, we're going to fix that. Yeah, it's here that it's not. Yes. Mm hmm. The service that we're going to go through actually returns an object that has value, I think was a valued value and father has order. All right. So let's just first deal with all the missing components that we need so observable for our Geass, our module. The environment always support from environment, environment, never import from production. That's something angular places and build time just if I. We need to catch the predator. Weird suggestion, this quote, Thank you, and we have a handler that will deal with in a little bit for now, just leave it all to generate little visuals to do or generate that. But do change the type to observable of any. And we're going to leave that for now. We have other plans for it. Oh, yeah, and I should say this is get all the orders. And since we want for this to actually return the trade that we care for in the data, we're also going to map this out. To the Vallerie. Was the euro and the environment going a bit too fast? I'm sorry. Yeah. The euro is an environment war, just two tips galore, everything coverable is insane, yeah, and environment. I called it orders and point, since that's what the snippets are configured for, if if you name it differently, just keep in mind when you plop in the snippet that you're going to have to change that button to the sense will help. I'm going to do a quick burst of the other guitar, that's just the singular order, which is get get order, order, that's fine. Although this time we want to pick an idea as a parameter. And what we're going to do with this guy is go ahead and use a template string. And passing the segment with our Eyedea so that we get a singular order. All right, so now behind on the imports, so maybe maybe show where most of the stuff is imported from so observable surrogates, the catch our map operators, again, from our chefs and the environment, should the first order suggest, should be environment. This coat should be good enough resolving those, although why it resolved source like that instead of going up is beyond me. That is a weird relative path on it, on that. Showing. So, guys, those are ordered in basically in the way we can add them, so if we jump to and the next option on the methods is post. And they're going to return an order and you're going to take an order. So post, by the way, get on your order, also gets an object of value, that is order. It should not. Shouldn't it know the singular get met that is supposed to return, the singular discovered? Oh, right, we got that from the FBI. It should be fined. So for the first just. Facenda, arta, yep, you know what, maybe we should have changed that, get AIPA orders to return a Jason of Datatel value instead of just data, but keep going. Already implemented it. Yeah, the only the only reason we kept that was because at one point you can you can go ahead and the environment and just put in the actual data service there. And everything should still work at least for getting better. Now that was the point that we're the ones that we tried to get across. Mm hmm. OK, so we have to getas and then and we'll do an update next, which is the next option in line, which is a put method. But Bédard also returns to order and we also take an order. And president. Those those should be going real fast. And then the last one is just delete. You tavan, and you should get the last option, which is delete, and this one actually doesn't return anything so void. And it takes an ID and it's actually really similar to the get through with I.D., so copy over once again. And you need. Oh, wait, I did a massive whoopsie. Did somebody got on that? I forgot, I forgot the template, the endpoint. This was going to get real wrong real fast. Oh, yeah, we can we can copy paste it now once once damage is is done, well, just going to we're just going to copy paste it here actually. Daming keep going. I committed some code to the original repositories show, so I should be able to actually send a snippet from there. That API is done though. Like, we have all of the corresponding methods in. So. I'm going to I'm I'm going to go ahead and commit that. OK, your place to go. All right. Yeah, because we're going to end up stranded for time at one point. So, yeah, cheating is allowed at this point. OK, so let's throw in a component to consume that service and data. So we're going to go once again to and generate generate components and GC. Sounds suspiciously like NGC. And. We're going to tackle this when to call this orders the one, because we're going to have an audience of two and we're going to give it. Can I. Oh, I can resize this. Oh, nice. We're going to have to specify a model so we have more than one module in our application and and can be angular, Saleha is going to ask for that anyway. You can just do modularly course app. True that, true that all right, yeah, moderate goes up. Fair enough. Yep, no work just fine. So one thing we're missing, this did register as a declaration in our main module, but it didn't do anything in the routing and I'm so not trained for that. So I'm going to go ahead and. Duplicate one of the other parts and go call it orders the one and bring in this component so we can actually see it in DUI. Let's see. Are you are you still working? Huh? All right, so everyone works. Unsurprisingly, there is nothing inside. So in our newly generated component's. We're going to go ahead. And inject our order service. And we're also going to define. A public array of hoarder's. And on the component in that, we're going to ask our service for data, so. Getraer's. And subscribe to that, and once our data is returned, we're going to go and say that the data orders array that we have in our component is now up to service returned. Oh, how did I put to underscore subscribe? Yeah, we can do a nasty pipe here just. Oh, true, true. So we can get orders directly as to unobservable public and and but just proceed with the template. Now, once you write the template, maybe we can show the difference then. So basically, you're going to talk about this as an observable in assign it directly, which is fine. Hmm. All right. So this doesn't have anything, and if you noticed in our data, we have a lot of entries with quite a bit of data or data properties on them, so it made sense to us at least to go and use that in a table. So let's try that one out. So I'm going to go ahead and create a table. And for the table, we need headers, so those are table header elements. And since I don't know, I don't want to particularly type out all the data right now. I'm just going to go and and for those out of the discourse itself. And because I need the actual keys, I'm going to call this a pair. Was it orders, it's orders going to grab the first one, which may or may not exist yet and pipe it through a pipe it to a key value pipe. So this will actually give me the first order broken down into key value pairs. The key value part is built into anger. If you're wondering. And for the headers, we're going to go ahead and say put in the keys of which property on the object. OK, we also need to show our data somehow so rose, so TIAR. And those are going to be very similar, so I will copy paste. Except we're going to spend on all of the orders this time. Hello. And for the cells. We'll need to create a few of them, so very similar to the key value pairs. We'll take the order for the control and split it in key value pairs and within the cell. We're going to display the property value. So. You've also said and done. This should actually give us a table. It's not going to be pretty, but it'll give us a table, hopefully. Except just to refresh, yeah, they've run on server side, rendering is somewhat temperamental, sometimes it refreshes, but sometimes it doesn't. Beats me. All right, so we've got this. It's. A table, it's not great for any measure. Let's try to improve it just a little bit. For example. We really dislike those they're ISO strings that come in from the data. And they're really hard to read in their current state, so what we can do is, for example, pick the order date column and you can go ahead and copy the header because we're going to use that and run it through a date pipe to format a little bit better. So, Damien, I think we should speed things up a little bit, OK? I swear. No, that's fine. I'll move what we currently had into a template. And I'm Niaspan. And check, the current property key is equal to. Or the date or the date else, and I should have named. The default, the template needs to be set as a template variable or else go into default now Angular complains for some reason for this because it can figure out what the type of the property is, since they're all generic doubt. And I haven't found a way to tell the key value pipe what types it's dealing with, even though it's acutely aware of what the orders are by this. Disregard this warning because everything will work out just fine. As long as necessary. Corporates, come on, buddy. Well, really. It hasn't turned out. It hasn't done anything. I am lost. But. And I guess this is about as much as a society will do for us. OK, just stop, hit and run. Yeah, that's exactly what I'm doing because it just died. So not helpful, Ceasar. That's very helpful. Just a.. Oh, yeah, come to think of it, up until what anger? Nine or ten. There wasn't a devil for this at all. Like, you couldn't run it and mode and develop at the same time with refresh. Right. And, you know, in order for it to be fast, it cannot recompile the entire minutes. So sometimes, you know, stuff like this happens. Brandon, yep, we're going to get there. Oh, yeah, I should have actually said that we want something in that template. Thank you very much. Yep. We're going to run through the pipe and sure, we can say that we won't short or we can go even fancier than that in a second. As long as my side actually decides to load. OK. So did short. Please cooperate. Are we all destroying your data service, is that what's happening, because that might that might be that might be something we do. Oh, God, not that there isn't that many requests. I mean. We have I hope not in. We have 50 people running, you know, and I request to that service. I really hope not. Yeah. But yeah, my thing is really not really cooperating today. Really up there, it's fine, it's fine. OK. So, as Brandon suggested, we can do different formats on this, but we can go more specific than. That format for a date short so we can go like Monk, Monk, Monk, which is like spell out the whole month and say Date City ere we can go. Give me the time, the hours and the minutes and ampm, for example. That sounds about right. Mm hmm. Yeah, I'm just not going to rely on this. Was that as tough as saying, like, you're axing orders of zero where you actually have an acting request to the orders so you can get an error there? It shouldn't in theory, because order is zero before the data has arrived, is just undefined. Right, and apparently the key value type just handles it like a champ. But yeah. You can probably fall back on that one. OK, so this is really unwieldy, like it's massive because there are about 200 records in this and there's no way to force the table to go into something decent in UI. So I'm actually going to wrap it in a do. And give it a some class, let's say, Tabo rapper. And just moved the entire table. Inside the div. And. We're going to define a table for upper class and give it like a height of 80 percent. And overflow out of. Which would give us a much more decent table to work with. OK. Yeah, we can scroll now and I have my why not overtaken by that grid? OK, so the last thing we're going to try to do with this is throwing a button. And unclick, we're going to call a not yet existing method saying can new. And we're going to go ahead and copy it up and go and define it in our component. And for this, we're going to need. A new order. And I'm going to cheat a little bit here. George is right. You can just coast, you can add height and overflow to the coast without the development for that. I accept that, but I I'm not going to go back and change it, though, but yeah, you can you can just replace this entire thing with host. And it should work just as well. Keep keep going, I'm going to resolve the next one. The pipe key value cannot be found. So you can sense the impossible from angular corer, right? It should be common. Yeah. All right, I'm going to spell out a few properties, OK, so customer would be Entercom and then, I don't know, shipping country. I'm entering Bulgaria because I'm biased. And shipping city. Would be Sophia, and the order date would be right about now, Sunia Date. So you can't really. And then we can send this to our service. You can see our daughter. And since the add up operation actually returns, the updated order back to us. If we want to grab that and add this to our cached current orders array without making a new request, when we subscribe, we can just go ahead and say this orders. Bush, whatever is returned. Assuming it's successful, otherwise it wouldn't really go through the general. Oh, it's trying to refresh. Oh, boy, is that a good sign. Noch. It used to work so good today when we tried it, I am officially given up on this. All right. So we have a bunch of orders. And then we slap a new one. Something obviously happened because the table sort of shifted, so. Maybe there's something at the end, hopefully. Oh, yeah, there we go. So we got a new. Entry that's not really filled in because we don't have all the property, isn't it, because we were lazy, but that's fine. So the columns are done pretty much right now because we're renting them just in order. But two one is the new idea we created since we have two hundred records and it went down just fine. Yeah. And Damiana, you should please commit. I am not sure why the common module wouldn't resolve correctly. It should be already included like everywhere. Like the browser module brings in the common module with it, and I believe the forms module does as well. So. There should be little chance of not being able to resolve and if for some of the basic pipes anyway, if it still doesn't resolve properly, maybe you can try to include it in the app module. But my guess would be to try rebuilding the Cezar, because, aha, yeah, that that's with the assertions sometimes acting up. Yeah, because it does some in here and there, and it sometimes doesn't refresh quite as good as you would want it to, for the most part, it's decent. All right, Damien, I suggest go go to the fancy car components now. Yep. All right. This was all what Olivia looks like. Yeah, it's working, but it's not pretty. And it's going to take a whole lot more than that to get it somewhere. So naturally, we're going to offer you something that's ready to go. OK, so again, we're going to generate a component, although this time we're going to generate it out of our own schematics package. So that happens the same way and degenerate, except at this point we don't specify generate component. But you specify the name of the schematics package that you want to use. So it took nine to I. Angular schematics and. Either component. If I can type or just a shortcut, see very similar to NGC, except you give it a schematic package to use and what's going to what this is going to do is jump into the options of our own schematic. And we do promise all the way, because we have way too many components to expose through singular components for all of them. So as you can see, we can jump to add a component and then we have some lists, we have charts, maps, gauges, data entry, we have interesting layouts like we have a dock manager that we may or may not get to to date. So we were doing a table. So the most reasonable thing to do is go into grids and lists, grab a grid, and we want a few features on it. So go ahead and grab a custom grid. Call it orders. Oh, wait. I should have committed this one. So my history is clear, so we named the component orders and now we know where we're going to create 24 Anjelah grid and we have some options that we can reconfigure out of the box. So those are selected with space, as it says in the end, and you can move out with arrows. So I want sorting out one filtering since we're doing anything I want from editing data and then I won't throw selection because why not Beijing? Sure. And then we can do honestly all the column features column being called column moving. Column hiding. And going to we're going to go ahead and hit complete and skip the trial package. And we don't actually need the search right now, since Necessar is already running, so I'm going to interrupt that one. So what happened? We got a new component. That actually got registered because we do that, it got declared in our main module, but also it got declared as a path in our writing routing module. So this should pop up as soon as Necessar decides to refresh or something and you go. And there we go. OK, so that popped up real quick. So we have a grid that's capable of quite a few things. So it has built in Beijing sorting, filtering, because you would expect we have a bunch of interesting filters. So, for example. I don't know how Bulgaria nope. We have Canada, for example, or the USA, so we can filter and apply multiple filters and we can open many columns in one area or just a few, and then we have a separate area. That's horrible. You can also just drag and drop columns around or just show them and hide them. OK, so that came out pre configured, but it also came out with its own local data because we sort of give you that so you can have something to view when you run it first. But we don't need that local data right now. What we're what we want to use is our data service. And what we're going to do is actually grab. Of this code from the component we just created with the simple HTML table and plop it right here. And of course, we're going to have to do with some imports that are nonexistent right now, so espera usual. Bring in the model and the service. Now, our data sources named orders, which no longer corresponds to what we had before. So this is orders. And I believe I deleted the title of some sort. And may or may not be used. We're about to find out. OK, so of course, our data schema changed completely and that's something that I don't particularly feel like we're writing right now. So we're just going to delete the entire section of columns because we have a snippet for that. And it should come up as grid dash cams. And just stop it right in. So what this will do, we have a bunch of columns that are defined, some of them are already pinned. Some of them are movable, editable, sortable, we can specify each of those per column. We also have a single column that's just not tied to any data field. It's just like look at computed field in this case where we're showing if the order has a ship date, sort of like as a visual confirmation for each order as it has it shipped yet. Right. So this is what you should end up with. Oh, and I forgot to mention, since we're doing API for updating, this also has built-In row editing, which we can take advantage of with just a few events in the second. All right. Yep, somebody said that we should change the primary key. Very true. Also, there's a title on the bar below that says Employees, which is obviously supposed to take orders now since we changed the entire thing. Constantly. We should have used the North Wind employees table, it would have been inside of replacement. That is right. Just saying, well, we decided to make it difficult. Yes. OK, I hear it all working on my end. All righty. OK, I'm just going to throw in one last finishing touch on DUI for Taghrid since we're doing a whole bunch of editing. I'm going to act like a freebie UI for anything, so in your app module, you would need. And I GICs. Actions, troop module. I'm going to just plop that into chapped for everyone to copy paste. Add that to the imports in Europe module. And what that will give us is access to an actual strip that integrates within the grid, so inside the grid. Create an action strip component that's really angular. It's not it's not really cooperating with me today. Yeah, but. Exactly, Excession Street, cool, very helpful, very helpful. All right. And within the actions, we can just say. Grid. Editing actions. And we can also see. We want the admiral feature enabled as well. And I'm just going to resort to constantly refreshing my application. Or that may have been the end of the room. Oh, boy, not now. Come on. I can just plop this one in to chat as well, if you will. Funny thing, it loads just fine on my end that sometimes I share my screen. You know what? I've had this with Zoom before. Like sharing screen just takes a massive toll on the system. In all seriousness, yeah. So what this should give us is something like this. So we have a floating UI that can help us delete records, edit records or add new records. OK, so now we just need a few handlers to cook this up. And. Actually, I'm going to go ahead and plug this one in. Infor just in our documentation, you can just go right ahead and cite editing and I guess Roob and they'll have the entire thing spelled out like everything in code done, which is pretty much what we're going to do right now. All right, so on the grid component, which is looking very unpleasant right now, so I'm going to. Reformats a little bit because this is not readable at all. We're going to hook up a bunch of events, so. We have. Route adept. I think you can just do one, just do the row at OK? Oh, yeah, because I already have. The method for it. See, that's a new. There are no. The only difference is that this would take a different event. This would be my real data event, ARC's. And we should no longer need this. So that's what's going to be left with the. And assuming nothing blows up. Coolio. All right, so I want to new record with the customer I.D. something because, yeah. I can titted the primary key, which is expected. Oh, I forgot to return the data back to the grid. That's going to be. A little bit unpleasant, but I'm going to show you the network request, I guess. Country, Bulgaria, and that should be good enough. And then something pops up and says, go ahead and it's right here down the grid and we have to tool one created to post requests to our service. OK, and then. I guess just due to time, we're going to skip this, but you get the point you have on the road deleted and. On Roett, it. Oh, no, it's just throw at this time. We're running Minka events, it's happening slowly but surely. So, yeah, two more events and you have a fully functional KRET service and do I. OK, Konstantin, I'm going to go ahead and pull up the next component, if you don't mind. Yeah, go ahead. How's everyone following along? Is it too fast to to slow? Raise your hands. Tell us if you're behind, all right. So like anyone is behind at this point. OK, that's great. So we're going to go ahead and run the same general command as we did before. So this time we're going to pick a different component because why not? So we're going to take this time, we're going to go ahead and take a chance. And we have our pick between the category chart and the financial chart. We're going to take a category chart and say, what was this? Stocks, companies, stocks. Yep. Company stocks. And again, we're going to complete this and it's actually going to run uninstalled this time since the charts are separate package within the ignitable product. And it's also going to air out, which is expected that I'm going to show you why. It's also wearing out because the component is added, but it still hasn't finished. Oh, this is throwing the devil for us. I was going to say you should probably killed. It's fine, sir. It's fine until it's not. Let's see what it does. I killed him on my own grave. Also, I think I forgot to commit the grid I did now. I am sorry. Patricia. So what happened is another route got out with another component that has a chart in it and something interesting happened this time it doesn't work. Now it's saying that it can't find the Gitmo element, which is not that reasonable of an ask for a Ceasar since. Extends unemployment. Apparently, the chart uses some custom Web components in there, and it's not that unreasonable to find a library that's going to do that to you, right? So what we're missing is a shim, because as the angular SSR guidelines say, use anything else and if all else fails, Shim. So to make to make the chart actually compile and provide this, I'm going to make a new file. On the group level of the project. Oh, if only visual studio made that any easier. And I'm going to call it. Server typescript, and we actually have a snippet for that, if it picks up yepp chips. Oh, Konstantine, yeah, you what? What did you made for the Despoiler? Oh, in the environment. Yeah, I forgot to the environment variable for that. OK, I hope everyone's following. I'm going to spell it out. What was it just. Just stroller, which is basically slash, just slash project name. Slash browser, yep. And my project name is. Well, this is leading to is your dust folder, and it will be contained in one folder, which is your project name, browser index, HTML. This is where we're going. Since for the Chhim to work. We're using Domino and Domino needs an HMO template file to create a fake window or fake document fake mux elements for you and what we are like, don't forget to install Domino. Domino was actually installed, by the way. You can specify it is an explicit dependency, but some of the USSR packages over to bring it in. OK, so this will work out of the box, although you're correct, you should probably install it just to so you can have it as an explicit dependency. Yeah. Under it, it's already. So Engler platform server already brings in Domino. Mm hmm. It's here. But as you say. Don't just throw them. And what were missing for the Shems was HTML element. And we want to take that from the window that Domino created and to our slight caveat with that, it says that property element is not defined on type window. And when you go ahead and look at what Domino does. OK. Yeah, this is totally the zoom sharing, oh, boy. Really? All right, I'm going to give up right now, Intellisense as well. OK. Visual Studio, Sonoko. I'm going to give you just the solution, so what Domino is using is the actual window definition, the window type the typescript keeps in the Dublin library definitions, except the window is not the window because window is actually defined as window type, plus a whole bunch of things, including each time element that are not included in the base type. So that's why we have to typecast that as well. And Ceasar went very down, that's fine. Did you import the Chhim? Nope, thank you, Konstantine. It is late, so the reason we're importing the Chhim and this has to be inside the module rather than just plopping that code inside Servatius is because of this import the observer module and because of the way those typescript files get transposed to JavaScript, whether that is something to do with the Web, spark plug ins underneath all of the imports and exports get moved up. So even if I try to patch something before I import the observer module, which will bring in all of the library fault modules with it and error out, if I haven't patched something, it's not going to work if I just put in code here. But it will. If I just import that, they can actually do this on top, which is probably better for the best, just like Zohn, just us, because that's how those are ordered and just taken. Note. 08 Adut. Subversions. And now we should be able to run this. If at all compiles, just commit before adding the additional service, yeah, yeah, I'm stopping here. At the end of it all, we're going to, I guess, in a different branch, in the same repository linked for GitHub, we're just going to publish the whole thing as an end result. Shoulder to shoulder shims file and inside the snippets, there is shims. So the only thing that the snippets doesn't contain is the last line globally Schimel defined and also the typing of the window. Yes, this. Nope. I have no more power in my machine to even show the snippet and I'll seriously fuck. It's like thinking about it, but it's not. At this point, I don't even dare run any performance measurements on this machine because it's going to go really bad. OK, so our app has risen. We have some grids and thankfully we have some chart. All right. There we go. All right. Of course, the charges with hardcoded data right now, but we're going to change it up in just a sec. Yup, please commit to absolutely everything. Thank you. OK, so we need data for the chart and we're going to keep it super lazy again, we have, what was it, company? Oh, God, please, snippets. At this point, I'm considering just rebooting my entire visual studio at this point, the ram cache is probably busting already. Yep. I'm just going to go and reboot the whole thing. Again, I can just always go into the snippets and cheat my way into this and just find out what I'm needing. It's companies data, as predicted. Companies data. There you go. Thank you. So the entire snippet plopped down a whole bunch of data. So, again, we're using a similar approach to the orders, a store, a fetch from North Twin to this time Nortman customers. And one addition, we need Fakher, which is a marketing data marketing tool. So we're going to go NPM I HACA. And we can probably put this in deaf dependencies. We're going to go ahead on top and import figure, sadly, it does not have a devoted expert, so it will be. As an alias. And the last thing we're lacking is a customer module model, so that would be another interface to generate so and generate I and models. Customer. And within this, we also can delete this because we have a snippet and should be. Models customer. And going back to the server, I should be able to import that one. All good. OK. I'm going to commit this one as well. Huh? Constantine, did we do a snippet for the data service for this? Or did we not? That's a good question. Let me check. We might not have. Oh, well, and generally the service and services. For customers. Custom. Customers, mm hmm. And just like the order service, absolutely identical and you can probably just copy paste. But I'm going to I'm going to type it up real quick. We're going to take an H2B client and let's grab this guy. Did you install Facher, by the way? Yes, I did. OK, yes. Yes, it did. My thing doesn't work and I didn't install it. Did you imported as an alias. It's already reported by the. Oh, yeah, but I don't have an import. OK. All right, I'm going back to the service. Was that raw a service the same way as the other one, was it still an object with the value? Yes, customer. Do you want some snippets? Yes, please. So I would so love snippets. And let me give you. Yeah. Although he can push them, see if he can copy this from Chad. Oh, boy, oh, boy. Just not the cost structure, because we don't have. Driven bus service as of right now, OK? Yeah. Just think. And so resolve observable, resolved environments and then you would need one more interface, that is the company stock. OK, so generate an interface for company stock. Fair enough. And if memory serves, it had one side or that there is pretty there was. Yes, there is. Thank you. Company I.D. in a month. OK. And, of course, we're lacking an end point in the environment, which is companies in point. You want me to share to share that as well? Let me see the question. Oh, no, I copied the wrong thing. It's just customers, right? The companies in point is. Customers. Which one are you looking for, API companies, companies? Nope. It's companies, it's not customers, but companies. API is obviously API slash companies because it makes sense. Yep, and now an interesting thing, we just need to take the data and plop it into the chart and let it figure out its own thing. So, yeah, that's very rewarding data right here. Did I name the service customer service while consuming? Yes, I did. And I'm going to have to stick with that. I think that was actually a mistake on my part when I was doing this locally. Did you tell me to make it to customer service? Mm hmm. I know. I don't think so. OK. So I don't need dusted anymore. But I will take. Should I get the company started, a company stock for the shark, you know, for the staff need the stock. Yeah, OK. I would just suggest to underscore subscribe. And if that all worked, I should be able to run this thing. And Konstantin, at this point, if this works, I'm just committing and handing it over to you so you can do the server caching because I feel like we're going to run out of time real fast. We're not going to get to the bus service, but we're going to commit it. And the Reppel afterwards, that that's what I was going to say. There are some parts that, like we wanted to get to, which are how the two components get into the same view and interact with each other with the, you know, the same data where the grid is not going to be bound to the orders, but it's actually going to be bound to the companies. But, yeah, we're going to skip that part so that we showed the other thing, the optimizations that we wanted to show because there were people asking about it. So clearly interest there. Right. Right. Yeah. So let me see. Mine is mine is currently running fine. Because it wasn't just now that it looks like everything is all right now. So, yeah, if yours runs fine and we see the charred bound, then you can hand it over to me and I'll finish with the last part planning on it. That's a very good question, actually. How do you deploy the express up into production? So actually, the angular CLIA does have a deploy command, which works with common cloud services and stuff like that. But if you're interested, I can show what I have for a production deploy for Asia on another application, but that's after Dimin hands it over to me. Yeah. So, Konstantin, I have your data, like, perfect. A lot of it. Oh, boy. Oh look, Seabourne, it's a lot of data, but. Yeah. Those random generated numbers really make it look super funky. OK, now it's yeah, that. So the last part. Yeah, well, I will show that for deployment, but for that part, why we first wanted to show the chart down to all of the data points and then to integrate it with the grid where you select certain companies and only those are shown as stock markers on the on the chart. But that's going to be available in the repo afterwards. We're going to commit all that. And so you are still going to be able to run it and see that. So, Damián, do you want me to share my screen now? Yeah. Do I have to stock my share for your start? I know your post now. I'm not going to just take over. Oh, OK. So, yeah, I'm stopping. I remember there's a sitting in Zoome that you can set to allow for others to override. Yeah. And it's really easy to find. By the way, I'm going to refer to my cheat sheet so that things are actually run faster because we're pretty much out of time now. We were showing earlier that this grid, for example, is bound to the service that we have on the server side. And when we run the page and get the server side thing, we get the orders rendered. But we also make a request for orders on the client side after the application gets bootstrapped. And that's a question that we got earlier which asked, are we going to show the server transfers to module? And so there is a minor change that I'm going to do and I'm going to add the server transfer state module to the observer module in the application. And then in the app module, I'm going to add transfer HGP and what I suggest is not going to do anything for me here. So I'm just going to cheat. I'm going get it from here. You missed on this the trance for. It's that that's why it's not competing, it's still not cooperating with me. I don't know why it's doing it for a while now. And see here, it's not cooperating with me either, but that's from Universal. And so I'm just going to copy it from here. When I added to the imports. So they're adding these two modules to that module and the server module, what it does for us is you're going to say, shouldn't you implement something? But it actually implements an interceptor. And also on the server side, it breaks down as a server cache, anything that it received from from HP requests that were made by the server and. An incomplete, compiled first to terror and then compile, I don't know what's happening. But let's see what what difference this makes. OK. Oh, I still have an unsafe change. I see what happens. That's going to be a problem. Come on. Like I said, the moment to start sharing, it's all gone, right? I'm not kidding. The last income we had a colleague of ours, Victor, and same thing happened to him as well. Everything was going extra slow. So let's see. I still had changes, not committed comp. successful. This this is a good sign, actually. Yeah, we're getting so let's let's open the network tab again and make a request again. And what changed is we make the documents or request, but we no longer have this orders service request from the client to the server because the orders service request has already been performed by the server. The response has been collected. And actually, if we take a look at the response from orders, we will see that down at the bottom. There is this script with the server app State. And if we take a look at what this response looks like. It actually has, for example, API orders and then there, you know, whatever API orders got, we have it encoded here. And what does what this does for for us is actually by just including two modules, it prevents us from doing double requests. And very often it's like the server side of your application would actually live closer to the API service that you have, even though it's a separate application. And now, you know, up just don't don't look at the fact that in this application we're building for the workshop, we have the server API actually in the express engine. In most cases, you're going to have, let's say, a core API that you consume within points from your services. End point would still be cached on the server side. So it's not only requests that are made with server get or anything like that on the server side, it's any request that is performed for, you know, data for other static resources that can be written in the in the server transfer cache. And so this minor change with with the two imports that is actually speeding our application. You know, it's increasing the speed of our application a lot. So I'm going to commit this. Cash strapped sponsorships. In order to show something else as well, that something else is related to our library, actually. And so in this application, Damián didn't show so far, but how the theming, how the look and feel of these components is achieved is by, you know, including our core styles as well as our theme. And and this include we're technically importing the theme for the entire application library. And then if you've noticed the the actually, I will need to scroll up a bit to get to that. But the size of the success right now is about seven or seven hundred kbps, the application plus the library, which is pretty large. But what we have in this application is we're actually not running the entire library because the library contains a lot of components and we've exposed the way for you to trim down the size of this, the access that is being produced by defining only the components that you use in your application and excluding the rest. And so what I'm going to do is I'm going to define a variable which says which components I have in this application. And we included a grid with paging. We added some column actions. We currently don't have a toast component, do we, because we did implement the notification bus. Right. But we have overlays. We have dropped down and those are like filtering inputs and so on and so forth. We have an in in several places in the grid. There is a ripple. If you're going to ask where the ripple is when you click on this button, for example, there is a ripple effect on it. And it comes from from this definition. But now I've just included them. What do I tell the styles, though? Whenever I include the theme, I tell the theme. Well, you know what? I want you to exclude all of the components except the ones that I've included. And I'm going to click save. Now, I should get an output for a different style and size. And as I said, the the styles were initially amounting to about 700 kbps, but now we're down to two hundred and eighteen just to this is between 20 and 40 kbps should be more towards the 20 sites. And we still have the application styling. I think I'm not including something right. Because of this. Oh, and I have an action strip. Right. But these kinds of optimizations are all included in the documentation of the product, and they're actually important because when you start it and while you're still developing the application, it's fine to run, for example, with the whole thing. But once you progress this, that you really want to optimize your application as much as possible, especially before you want to deploy to production. And now, before we go, there was a question about deployment. So I'm going to show something here. I know that we're out of time, I just because there was a question on that I really want to touch so far and. Tom. Latest. How do I hide this, I can move it nice. So let me show something here. So this is my Asia pipelines, Yamal, because my application was the main built because I have three build's, but the main built that actually does the deployment runs through easier pipelines. So it's pretty much a standard built which does installation, then runs and then runs tests and then runs the build the production build with server side rendering. And before deploying the artifacts, I do something that is cool, that that is a small batch script. And the what the pre deployed does is because with server side rendering output that we get by default, I was having trouble running this application on Azure or Asia. I don't know how you call it. And so this type of structure, where are all the client files are all dumped into into the browser folder. And then the main server module, as well as the rest of the lazy loaded server modules are dumped into server folder. I was having trouble initiating the correct is node run on this server and then for this server to correctly access the browser folder afterwards. And now part part of the reason that was happening is because if we look at the server file, for example, I have two applications in this. That's why there is two server files. There is like two. There's actually three source folders because there is reuseable services modules and some of the components are reused. And so what I do here is I have separate environment set settings for the disk folders for the applications that are for production and for Dev and so for Estacada Dev to run. I still have the same structure that we had in the workshop just now. But for production, I just have a browser folder that comes out of root. So Truitt's browser where the application of this and in the pre deploy, what I do is I move everything from the server folder to the root folder so that there is not just runs directly Domingues, a server, and then everything is accessed in a browser from from there. And the deployment from that point onwards is just. If I go back to the Asia pipeline, Samel, I just published the test and then I have to separate deployment procedures, one for the Ebele folder that I have in this and another one for the other folder for the four for the second application. And the deployment is just take the files and deploy them, you know, pretty much file deploy them on Nasher and post deployment. Run the highest node with Mangkusubroto. All right, and I know I'm seven minutes over time, but, um, constantly and I can just mention that if you look at the package, Jason, what you have first serve Elsasser is basically the simplest script on Earth, which is like Noad this file. Oh, you don't you don't have it, but it's in the other projects and the new ones, your template might be a little bit dull these days. Yeah, actually you know, this application was started with angular four or something like that. So, yeah, like I said, but in the projects everyone got today, if you look at the surf setting, it's just Noad slash gists server manges. It's just like run this file. That's it. Yeah. That's the entire application right there. And it's actually great because I had to book that and this makes it a whole lot easier to imagine. Well for me it's slightly different because as I said, we, I have two applications, so I actually use the one concurrently to start both of them on the same time. And yeah, yeah, those things evolve with a real application and we try to really touch on how things evolve with this workshop. And I really hope it has been useful for everyone who's been watching. Yep. Also, we're so plugging them just right now. What we're so plugging the Belgian side right now. It's a great site also made from scratch by Konstanty and maintained lovingly. So you can check it out. Do you have a the chat? Oh, yeah, or is it through the link for the GitHub repo and it pretty much has has the link to the actual running application as well right now. Yeah, by the way, if like if you have trouble with things like, let's say SSR, this application, together with the application that we're committing for this workshop, would be a pretty good reference to answer, you know, how how other people have have dealt with issues. Now, if you're wondering, like, for example, here I also have the server state transfer. Right. But there is there is a slight caveat to server transfer when you do authenticated requests, especially to third domain or like, you know, when when not your applications. Domains are not matching. Authentic, authentic, authenticated requests would actually not pass because the authentication cookie will get blocked and not sent by the, uh, by the user agent. And so those requests you actually have to explicitly exclude so that you don't break your application by not making these requests on the client. Because, you know, that's that's a common thing that happens actually after you implement the service state transfer. Yeah. Just anything like that hit me up at any time I can, I can answer a lot of questions like this because I had to bang my head, you know, for a lot of these things for quite a while, because I'm I'm putting a link directly to the running, as I put it, running optimized server side, rendered fully functional app. Some it's not it's not for Democrats, it's Konstantine is go side. That's great. Hey, guys, I want to take a moment to thank you for all the time that you put in. I understand.