Advanced Usage of ag Grid | Brian Love | EnterpriseNG 2020 #ngconf

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] great uh you should see my screen now and let me switch over to keynote excellent again welcome uh we're going to be spending a couple hours learning about the advanced usage of a.g grid my name is brian love and i'm gonna be your tour guide for the next three hours uh i'm a google developer expert in angular and web technologies and i really enjoy traveling and so here's a picture of myself on the left i did a hike to the top of i think it's i might mess up the pronunciation it's in norway called a precious price shkolin uh which is a beautiful lookout over a fjord uh this is my wife and i in the top right in spain from last fall when we were traveling and i'm currently as i mentioned earlier residing in portland oregon in the united states one of the things that i'm really passionate about is certainly learning and teaching and being a part of that but i'm really passionate about a concept called learn in public and i wanted to share this with you here at the beginning before we get started i really like the idea of learning in public while you can certainly learn and i think as technologists we're learning constantly and you can kind of learn and keep it to yourself and and there's nothing wrong with that by any means uh in order to get your job done or to learn a new new skill or new language or new framework but i think that there's a real unique advantage and an opportunity to do what i call learning in public and learning the public can look like a lot of different ways for different people this can look like maybe speaking or being part of a meetup group or blogging writing a book whatever it is but i wanted to come up with a way to make it easy and so i i built this website and an application in angular called lookout.dev and the goal is to make it easy to learn in public so it's free you can sign up and it's really easy to go in and share that you've learned something for example alex akushko who works for google just shared something today that was really cool that i learned from him just by reading it in terms of improved typing around extracting keys and properties from objects and enums and so it was really cool that he shared that with us i would not have known that and so if you learn something today and you want to share it you don't have to but this is an easy way to do so so you sign in and you can share your knowledge what i call a lookout and you just add a quick description about what you learned you can add some instructions around maybe things to do things to avoid things to consider and why and then you can have some code snippets at the bottom you can have some examples of maybe what not to do or you might have examples of what to do and so it's a really easy way to learn public check it out if you want to learn more it's at lookout.dev jason already kicked us off with some housekeeping but i want to add a little bit more to that of course i want to reiterate uh the code of conduct jason already did a good job spelling that out for us just want to make sure that we double reinforce that we are going to run this workshop on mountain standard time so i am currently in pacific standard time in the united states so it is 109 pm on my clock we're going to run this workshop from 2 p.m to 5 p.m mountain standard time of course that's not everybody's mountain standard time but we're going to kind of sync up on that so um so we'll be with each other for the next three hours i'm going to try to give you a brain break or a bio break if you will every hour if you need to step away of course do so but i'm going to try to build in you know at least five or ten minutes that you can step away and and take a break and go for a walk or stretch or whatever it is that you need to do if you have any questions certainly raise your hand or use the q a panel as the best way actually so if you in zoom i think down at the bottom of your screen if you hit q a you'll be able to put in an answer and i will diligently go through and provide answers to all of your questions real quick some prerequisites to get started with um i need i've you need to know javascript and typescript because we're going to be doing some advanced things here you also need to have fundamentals of angular knowledge and rxjs and hopefully if you either attended the ag grid session this morning or you're already using ag grid that's going to make for a really better experience as you do the exercises and follow along so hopefully you've got some knowledge about eg grade fundamentals here's what you can expect from me for the next three hours i'm going to teach you something i'm going to show you some code i'm going to walk through a demo i'm going to show you a demo in the browser using the demo application and then i'm going to give you an exercise i'll give you a few minutes to work through that exercise i've given you instructions in the exercise and instructions in the actual code sandbox so we're going to be using code sandbox io for you to do those exercises and then we'll go ahead and we will work through the solution together so i'll actually go through the solution and type it up for you and reiterate that learning knowledge so the agenda for today and i'm actually going to reorder this real briefly but we're going to start out with immutable data and so this works very well with ngrx you don't have to be using ngrx and i've written all of the ngrx for you so if you're afraid of it or you've never used it or you're using something else and when i say afraid if it's just not your you don't want to get into ngrx that's fine the only reason we're going to be using ngrx is ngrx provides one of the key concepts of ngrx and redux in general is the idea of immutable data and we're going to be using immutable data in order to update add and remove data in our grid with ag grid and so again i've already written the ngrx for you if you're using another solution for state management and angular keta mobx ng-xs or maybe a hand rolled solution this would still apply we'll then going to take a look at styling agreed actually i'm going to reorder this because i want to get into the custom cell render stuff right off the bat and i'm a little i want to make sure that we get through the timing on this this morning's ended up perfect with the timing we got right through all of it at the very end uh but i'm not entirely confident on the timing here so i want to make sure that we do this first so after immutable data we're going to jump into the cell renderers and this is the exciting part honestly i think for all of us we're going to be using custom angular components in order to extend the functionality of ag grid and we're going to be doing that with cell rendering filtering and editing and so this is going to be a really exciting part of the story for this afternoon and then we're going to get into styling ag grid and cell editing um we may do cell editing first we'll see how this kind of goes i'm pulling a last minute change here um the styling section is certainly good but it's perhaps not as advanced as maybe i think some of you might be looking for and so that's around theming and customizing the look and feel of ag grid as was mentioned we're going to be using a demo application in order to go through some of the demos and some of the teaching so if you haven't done so go and go over to the demo application so let me fix this this is clone so go ahead and clone out the repository jason has already put a link in the chat for you so go over here and clone out this repository once you clone out the repository you're going to see an angular directory you need to go in there and then once you're in the angular directory run the npm install command and then of course at the end of that run the npm start command when you do so you should see the demo application go ahead and open it up in your browser and it should look like this we've got a whole bunch of demos here on the right and then we're going to look at those on the right the links on the left and then the demos on the right so we've got for example here's like a default editor where i can edit values and so we're going to be working through some of this demos in the application together so make sure you go ahead and grab that if you haven't already it's a great opportunity to kind of follow along with the demos and get to play with it with that said let's dive right in let me make sure i don't have any questions um [Music] okay good let's talk about immutable data let me real quickly mention these pictures are all mine i should have mentioned this in the morning session um these pictures are all mine from traveling last year so i think i'm going in the reverse order of my travel journey so i think we're going to start in spain and then we're going to get up into the baltics with estonia latvia lithuania poland will be some pictures from austria and germany and then i don't know if i made it on my pictures all the way to norway we'll see but you gotta follow along on our journey so we are currently in spain on our pictures on the right uh so let's talk about immutable data and some of the advantages so one of the advantages is we can synchronize data with a store right so if i've got data in my store if i've got ngrx or keta mobx ngxs and i've got data in a store it's it's really great that i can leverage this immutable data with ag grid in order to synchronize the data between the store and my grid so the grid state is maintained and this is a really big advantage of immutable data versus some of the other methodologies for updating data in at grid for example an ag grid you can bind to the row data property and set row data in through a row data object whether that's maybe a synchronous with an observable you can use the grid api to set row data but what you're going to see is that the grid state is not maintained when you set new row data in and what i mean by grid state is i'm talking about things like selected rows and columns filters sorting and more and so with immutable data as you change the data in the grid the grid state is maintained this is also very efficient when compared to some of the other ways of updating the data in ag grid so this is very comparable to the transactional updates that are also another method for updating the grid data so it's a very efficient process in which we are taking data from an immutable data source and presenting that data into a grid using a g grid as i've already mentioned several times this works really well with immutable stores so ngrx kita mobx ngxs and more as i mentioned also i'm going to be using ngrx you could be using something else but i've already written that for you so let's go through this together so there's a couple requirements when working with immutable data in aeg grid the first thing that we need to do is we're going to have to implement a get row node id for tracking rows and this is going to return an application assigned unique identifier for each row so probably if you've got a model maybe you've got customers orders you've probably got a customer id or an order id and so you're going to use that for tracking of rows this can you can think of this as like akin to the track by function in the ng4 structural directive in angular when a row so a row is added when ag grid is going to do kind of a diff right it's going to look at the id that is not already in the grid and if you've got a new id it's going to go ahead and add that row in a row is removed when the id does not exist in the row data but uh and right and no longer exists in your your row data but is in the grid and then a row is updated by checking object reference and this is important right so it's not like if you're used to doing like angular for example change detection uses what's called a differ function underneath the hood which is going to do a deep comparison so if you've got you know a thousand rows uh you know and each row is an object an object has all these properties in order to determine if any data has changed it's got to do a deep comparison and check inside of every object if some some value has changed to basically recursively iterate through the object properties however if we're using immutable data we don't need to do that because we know that whenever we change data with an immutable data store we always return a new object and so because of that ag grid can take advantage of that and simply do a simple object reference comparison so it's a much more efficient comparison to basically say hey do i have a new row oh this is not the same object let me go ahead and change the data in the grid for those of you that are star wars fans maybe this should have been a trivia but maybe you could think about a star wars movie where this particular shot might have been in a star wars movie i know jason's a big fan i don't know if he's stepped away but uh try to remember maybe what's seen in what episode or you know of star wars and i believe there's a scene that happens here and again this is in spain and the camera kind of pans along as they're on this kind of i'm not sure where they're supposed to be maybe jason can come up with the exact uh planet and and everything uh for us but this is uh i took the shot to try to replicate uh that particular scene so kind of a fun tidbit okay let's go and dive into immutable data so let me pull up my thing here and so what we're going to do is the first thing we need to do is we need to set the immutable data property to true on the aeg grid angular custom element here you can see that i'm using row data and i'm using the async pipe with an observable to pipe in the data to my ag grid angular component i've also got my column definitions if you attended the session this morning or if you're already using ag grid this should look very familiar and then here is the get row node id input binding and i need to provide a reference to a function that's going to be invoked that returns the unique identifier for that row node notice that this is a function in my component and i'm not invoking the function so there's no open and closed parentheses after the name of the function i'm simply providing a reference to that function and a g grid is going to invoke that function as necessary so very similar to the track by behavior with the ng4 structural directive here is i've got an immutable component and here's where i'm implementing the get row node id method and so this is receiving a node in this example i've got a customer object that i'm getting of type customer and then i'm going to return that number that's a unique id and i'm just going to go ahead and return the customer.id value let's go ahead and take a look at a demo so go ahead and open up in vs code or webstorm or whatever code editor that you use and open up inside of the source directory there's a features directory and then inside of there we've got a data directory and then inside of there we've got an immutable directory and i'm going to do that as well so we're going to go to features data immutable source app features data here's our immutable component all right so let's walk through a couple of different uh aspects here some of this is going to be a little specific to uh ngrx but a lot of this if you're using immutable data storage this should uh you should be able to swap this out with whatever you're using so in the engine init lifecycle method i need to go ahead and dispatch what's called an action again don't be too concerned with the ngrx side of this basically i'm saying hey you go go fetch some customers for me please and it's going to do that here's our get row node id method that we have to implement for the immutable data store i saw i showed you this earlier where i'm basically returning that unique identifier for the customer id and let's come up and take a look here's my customers these customers are this is going to be what's called a selector in ngrx but again if you don't use ngrx don't worry about it basically know that customers is going to be an observable of an array of customer objects and they're immutable so if i change a customer i'm not going to just change let's say i change a customer's name if i go in and change the name from brian to jason i don't just change the name property in that customer object i actually return a new object so it's basically spread spread the existing customer and then we're going to return a new object and overwrite the name property value and so because i'm using immutable data this is how i can leverage immutable data stores and synchronize that data down into my grid with ag grid a couple other things just to quickly show um this is you know i've got a form that i'm i'm building uh this so i'm using reactive forms for this uh here's my column definition you can see that i've i'm outputting some of the customer information for my grid i've got a selected customer so when you select a row i'm going to select that customer again you know most of us in the i hope all of us in the room are very familiar with this with a g grid if having used it or at least attended the workshop this morning but this is where i'm tracking the selected row so i'm using the grid api to get the selected rows and then i'm going to store the selected customer based on just the first row that's selected and i'm going to patch that value into my angular form group finally the on submit method is going to save the new customer data again i'm using ngrx here but the important thing to note is that i'm simply saying hey go update this customer this is going to run what's called a reducer function which is a peer function that's going to modify the data in my store in an immutable method or an immutable way and so this is uh what our component looks like let's come over to our template here i've got the immutable data property set to true i've also enabled row selection so you can only select a single row here's the grid ready event emitter and i'm invoking the on grid ready method in my component in that class and passing along the event object so that way i can get access to the grid api here's the selection changed output emitter or event emitter so when a user selects a row i'm going to invoke that on selected change method that we saw previously here's the required get row node id input binding and i'm binding to a reference of the get row node id method in my component and of course we've got our row data up here and i'm using the customers observable that's returned from my store so in this case ngrx and i'm using the async pipe to subscribe to that observable and then of course as we're used to seeing in pretty much every eeg created instance unless you're doing some really cool things with the column and grid apis i'm defining my column definitions i am using angular material but basically i've just got a form group down here and this form group is where i can modify the customer that i've selected the key here is the on the submit output binding and i'm invoking the on submit method in order to send that data uh to my backend or to my uh whoever is going to deal with updating of the customer okay uh let's go ahead and take a look at the demo so this is under data immutable okay so down here if i scroll down a little bit should i bump this font size up one more sure okay so here is my immutable data i've got all of my customers in my grid up here and here's my edit customer form you can see it's empty right now let's say i select the first row now i could come in and let's just change this my wife's name is bonnie so i can change that to bonnie i can hit save again uh you know ngrx is doing its thing it's it's modifying that object and returning or excuse me returning a new copy of that object so we're using immutable data and then if i come up to my grid i can see that this row was updated accordingly if i were to add additional data into the grid it would compare the customer id and add it as necessary if i were to remove data from my data store and it's no you know and it's still in the grid ag grid is going to see that and then remove that row from the grid what the the kind of key takeaway here is first of all this works really great with if you're already using an immutable data store uh this is a great solution secondly and most importantly perhaps is the performance benefit of this if i've got a lot of data i you know in my grid and i've got a lot of state changes to the data that's in my grid synchronizing this data in a highly efficient manner is something that is going to be almost necessary trying to re-render you know 10 000 rows or a million rows of some sort of data every time one value changes in one cell is not an efficient way to do so right so if you've got an application where the data is changing rapidly or you need efficient uh you know mutating of that data in the grid adding removing rows and modifying existing rows this is a great solution and then furthermore if you're already using a data store this is a great solution for synchronizing the data between your data store and aeg grid so this is a really incredibly powerful feature that ag grid ships with and this comes in the community edition of ag grid i don't think i mentioned this already everything i'm going to show you today is all in the community edition of ag grid so the community edition is free and then they also have an enterprise edition which is obviously not free and comes with additional features functionality and benefits i should also mention while while we're real quickly on the topic of enterprise edition i don't work for ag grid and i don't get any sort of royalties off of you purchasing so i have no skin in the game if you will i'm just want to teach you what i've learned about aeg grid and i'm happy to be here today so by no means am i trying to sell you on energy grid i use it personally and i've said this this morning in the workshop you know i do a lot of angular consulting and web consulting in general with clients and i've worked with very large enterprise clients and ag grid is well suited for those types of applications and so i certainly when i need a grid and a powerful grid i looked at ug grid as a tool to bring in and to use the features and functionality that it provides so okay let's go back over to here and let's do an exercise so let me go ahead and copy this for you let me go ahead and put this in our chat window uh as i mentioned we're going to be using code sandbox for doing some of the exercises and while you get that up and running you can sign up for a code sandbox account using like github and such or i think you can actually just not sign up if you don't want to keep you don't want to save these the first thing i want to show you that's kind of a tricky part about code sandbox is it's awesome that they have this live preview on the right unfortunately it kind of gets stuck sometimes has been my experience when building out these exercises and so let me boost the size of my display here and i want to show you this icon up here so oh sorry that wasn't what i wanted ah let's get a big arrow wow that icon right there so if you hit this icon this will toggle the browser that's on the right and basically what i do when i'm working with code sandboxes i'm like listen i don't want you to update like every keystroke and it'll error and sometimes it'll get stuck for whatever reason i'm not sure i go just hide that and then i work through my exercise or work on the solution i code it all up and then once i'm kind of ready to test it out i hit this i bring it back i let it do all its magic and start to display things for me you may notice if you don't do this that code sandbox may kind of crash it did that to me a couple of times um at one point i thought my laptop was going to elevate off my desk the fan was spinning so hard so just go ahead and close that and then work on the exercise so i've given you the exercise what i want you to do is when the user selects a row which is a customer and clicks the delete button i want you to delete the customer from the store so you're going to enable single row selection as i showed you you're going to track the selected customer using the selection change output binding on the ag grid angular component and then i want you to enable immutable data and implement the get row node id method and then we're going to implement the on delete method to delete the customer from the store so let me go ahead and leave that up for you on the screen if you've got any questions in the meantime please feel free to put those in the q a happy to answer any questions that you may have this one's going to maybe take a little bit of effort i it is 33 after my time and so it's 1 33 p.m pacific standard time why don't i give you seven minutes so we'll pick this back up at 40 after and i will walk through the solution with you and i'm gonna stand up i've got a standing desk i like to change my position throughout the day so so oh maybe he did add it perfect yeah and he did add it to the q and a i'll let you pick that up can immutable data work with the server side row model data source yes is my understanding i would double check the docs andy but i believe so i have the reason why i say yes question mark is i have not personally used immutable data with the server side uh enterprise edition of ag grid um but based on just reading their docs and kind of following some of their code i believe so if not let us know throw it in the chat or something if you figure out otherwise some other people might be interested in knowing that as well okay let's go ahead and move along to the exercise reuben no worries if you can't code along um keep watching hang out with us for the next couple hours if you want hopefully you'll be able to learn a lot there um and uh you can always re-watch this we're gonna have these recordings available and you can get the links and and kind of go through the exercises if you want later all right let's do the exercise together so we're gonna when the user selects a row which is a customer clicks the delete button delete the customer from the store so let me pull this up real quick all right so we're going to go to app component and we need to have this on selection change invoked so let's go over to the template real quick and here we need to do uh was a selection change let me just double check my selection changed and we're going to call the on selection changed method and pass along the event object while i'm in here i might as well just set the immutable data to true and i might as well also set the row selection to single so we allow row selection i've got my row data in here and my column defs so let's go back over to our app component i've got the grid api here and so what i need to do is i need to get access to the selected customer so let's go ahead and do that so i'm going to do const selection and we're going to get from the api we're going to get the selected rows i'm going to just check that there's a length so i'm going to say if selection.length equals zero let's just get out of here oops let's just get out of here and do nothing otherwise we're going to do this dot selected customer which i haven't defined yet but i will and we're just going to pluck off the first selected row so let's come up here and define a selected customer so we'll do private selected customer is going to be of type customer all right so we did that let's go back over to here i did the row selection but excuse me the immutable data but as soon as i do immutable data i know that i also need to use the required get no row node id so let's go ahead and implement that so we're going to do get row node id and i'm going to give it reference to the get row node id method in my component so now i need to define that so we're going to do get row node id and that's going to return a number i'm going to return uh oh it's going to get the custom be past the customer and i'm going to return the customer.id value so again similar to the trackby function okay so i've got my selection changed output event emitter i got my input binding for the get row node id i'm giving it the get row node id reference i've set a mutable data to true i've got row selection set to single all right the next thing i need to do is when the user clicks the delete button i need to delete the customer so what i'm going to do is go over to here i've got on delete and i want to delete the selected customer and so there's a little tiny piece of ngrx here that i need but i gave you a hint so i'm going to dispatch off this delete customer and the id is going to be the selected customer id and i should probably check that i have a selected customer so let's just say if not this dot select a customer and let's just get out of here it's kind of a little bit of a guard there okay let me go back to keynote yep i don't want to stop you too much but neil has a very um time appropriate question in the q a oh that's a good point um yeah neil that actually would probably be more efficient so thank you for pointing that out what neil is saying is why bother doing the selection changed what i could do and probably should do is just up here so i could have a grid ready method which i don't have so i'm accessing the grid api here but neil you're probably familiar with the grid ready uh method or event emitter right that output binding on the aeg grid component here i could have done something like grid ready and then i could have said on grid ready it passed along the value i'm just going to leave it out for now then i would have access to the grid api and then at basically at the time that i actually need the selected customer id when i go to delete it then i could just use this same snippet of code say hey give me the selected rows if it's equal to zero i don't do anything otherwise i know my selected customer i go off i dispatch and delete that so that would certainly be i would say another approach and perhaps arguably a better approach rather than tracking the selection changed every time the user selects a row so really good point all right let's go ahead and try this out so i'm going to open up my code sandbox and let's hope this works see if i didn't try deleting myself and there we go we can see that that row was deleted because again remember that get row node id over here now this saw that the that row node id no longer existed in the row data which is that immutable data coming back from my immutable store and i'm unwrapping if you will using the async pipe to subscribe to that observable and binding that down into the raw data but really good question i love it and keep them coming um you know i want this uh to be you know learning for both of us so if there's something that you see that you've got another idea or you're like hey what about this uh throw it out there for all of us that'd be great okay let's see i had talked about changing this up and what i want to do is i want to get rated to the meat of this and if we've got time uh we've already we're an hour in the immutable data is a great thing to learn but i want to get right into the components so i'm going to skip over the some of the styling aspects and we can get into if we've got time at the end we'd love to take you through the styling stuff and you can check out the docs on on styling as well but we're actually we're going to skip unfortunately you're going to miss some of my pictures from uh some of my other travels but oh well so here we go let's talk about building custom components to extend the functionality of ag grid with angular and so i really love this and i get excited about this section because it's really powerful now ag grid certainly ships with a very rich set of features that i can leverage to do sorting filtering i can i can kind of override things like the sort order i can do all kinds of really cool things around you know the paging of data i can do you know we saw this morning if you were with us we did the infinite row model where i can infinitely stream chunks of data into my grid but one of the things that's also really cool about ag grid is the ability to build on top of aeg grid using components now this is certainly an angular workshop if you work at an organization or a in a shop if you will that uses other frameworks there is certainly the same most very similar solutions for other frameworks so you can build custom components for a g grid with react with view i believe they've got smell i'd have to double check i think they've got uh or at least started to add felt support and then the other thing that's really neat is maybe work in an organization that uses multiple frameworks for your front-end technologies you might be using angular and react or angular and view you can actually write web components so kind of going down a little bit lower you know less abstraction you can write web components as custom components that extend the functionality of ag grid and so i had a question this morning about will should i write it as a web component or should i write it as an angular component and the answer to that is really based on your organization if if you're an angular organization and you don't foresee using other frameworks in at least the near term then i would just leverage your existing skill set and knowledge and write the component in angular if you are using multiple frameworks that's where you're going to want to probably look at using something like uh you know web components again this would be if you want this component to be shared amongst you know projects that are using various frameworks but if you're using angular and that's it and i will just go ahead and write out these components using angular like i said this extends the provided functionality of each grid through custom angular components so what are some of the components that we can build we can do custom cell renderers so we can not there's a cell renderer property in the column definition where we have a function that we could return html string or an html element and provide a custom cell renderer but i could take that a step further and provide a custom component to do the cell rendering i can do the same thing for editing of values i can have a custom cell editor i can have a date component i can have a filter component we can do a floating filter component we're going to do that here in a little bit i can have a custom header so that that top header of my ag grid i can have a custom header up there custom loading cell a custom overlay status bar tool panel and tooltip and some of these other ones are enterprise only just a note so we're going to build some custom components we're going to build a filter component we're going to build a renderer component we're going to build an editor component and we're going to build i've got filter here twice maybe we're just doing the top three sorry about that uh no we're doing a header that's what i meant to put here just fix that and we're going to do a custom header component why don't we actually take a quick break we're at the top of the hour and i want to make sure everybody gets an opportunity if you need to take a brain break or step away why don't we take uh let's do it's two of why don't we pick back up at five after so why don't we take seven minutes uh why don't you if you need to step away because this next section we really need to spend some time and focus in on it and i don't want to go too long without a break so let's okay uh we are at 7 after why don't we go ahead and get started with registering components so in this section what i want to do is i want to teach you how we get started with these custom components and the first thing that we need to do is we need to register the components and so the way we need to do this is there is the static method which you've probably seen on the age grid module so the ag grid module is what we use inside of our ng module inside of that imports array in the metadata for our module we use the ag module class and then we invoke this static method called with components and if you're not using any components you probably just pass in an empty array but this is where we're going to register the components globally for use in a g grid the second thing that we need to do is we need to register them by name via the framework components input binding on the ag grid angular component you will also see in the documentation that you can register components by reference and there's kind of some pros and cons around this my general takeaway has been and what i tend to follow is registering them by name so i won't be covering registering by reference so we're going to we're going to register them by a name and then we're going to use that that name that we specify as a key to tell the grid to use this particular component for a filter or whatever it is that we're going to do so here's how we do that so here is my agreed module with components and here i am registering a bunch of components so i'm registering all these components with eg grid so i've got a currency renderer component i've got a date filter component i've got a material header component that we're going to use and we're going to learn and i've got a slider filter component the next thing we need to do is we need to tell the specific grid that we're working with about the custom framework components that we would like to be made available and the way we do that is through the framework components input binding so i'm going to use this input binding on the age grid angular component and then i'm going to provide it a reference to the framework components property in my component class and this framework components property is going to be an object where the key is the name and then the value is a reference to the component itself let's look at that next so here i have a filter component and inside this filter component i've got a property called framework components and i've set that equal to an object and i'm registering these components by name so there's no double quotes around this because it's just this you know it's a valid property name for an object or in other words it doesn't have any dashes or dots or anything in it and so the name that i'm registering this component under is date filter and then i'm giving it a reference to my date filter component so this date filter component this is an actual angular component this is a class and so i'm importing this at the top you know using an es6 import and i'm bringing in the reference to that component again here's my slider filter i'm registering this component by name and i'm giving it a reference to the slider filter component that i've imported up above once i've done that now i can actually use my component where appropriate so if it's a filter component in this particular instance let's say i've got a date of order field so this is i've got orders in my table and this is a date that the order was placed and i want to have a floating filter component that's a custom component that i'm going to build i don't really like the built-in date filter it just uses uh the like whatever your browser's filter is which is okay but it's really not that highly usable and i may want to have a consistent user experience across you know devices browsers and os's and so i might want to use a custom filter component so what i'm going to do is i'm going to turn on a float the floating filter and then i'm going to specify the floating filter component to use and in this case i'm going to give it the name of the filter that i'm going to use so notice that it's in single quotes and this references back to the name that was registered so that is the name of the component that i registered once i've done that i could pass along params to my floating filter the parameters that you pass along to your custom components are going to be uh the the built-in parameters based on the type of component that you're building so for example i'm building a floating filter so you can pass along all the default params that you could pass to any floating filter and further you can extend that interface for your own custom component and pass along additional custom parameters to your component that you're building so in other words you could allow parameters in here for your application and your needs whether you want to do like some feature toggles some ui toggles or whatever it is that you need to pass along to that custom component okay uh so here's the component interfaces so there's an interface in general yeah yeah so there's an interface for each component type and this is what's going to do uh it's going to enforce a code contract right and that's exactly what interface interfaces do so every component custom component that we're building for ag grid the first thing we're going to do is we're always going to implement this code contract via the interface so we'll have the name of our component so i have like export you know class date filter component and it's going to implement the i floating filter component or it's going to implement the i cell renderer angular component and this is what is going to help us to ensure that we are meeting the code contract when creating a custom component for aeg grid so let's take a look at it first to get started with we're going to take a look at a cell renderer component and then we'll take a look at a filter and then i think maybe a header and then also a cell editing component so the cell render component is such so by default the values that are rendered in a cell are rendered as simple text so whatever is in your row data or whatever data you supplied ag grid it's going to render that as text we can use a custom cell render component to render simple to complex html if you were with us this morning we looked at the cell renderer property in the column definition object and it certainly can use that to provide a custom html or to provide an html element that's going to be rendered in the cell but if i have additional features or functionality that i want to be able to render i can use a custom cell renderer component the other thing that i like about this is that i can encapsulate the logic of that cell render so you may have a cell renderer in several of your grids and they're all doing the same thing or maybe you break that function out and you put it in a file and import it and that's a good step forward but if you really want to take a step further perhaps you may want to encapsulate that logic into a component and then you can reuse that component between grids in a project or perhaps even an organization if you've heard of nx which is an ability or angular workspaces where you're using multiple angular applications and you're sharing resources between those this would be a great opportunity so if you've got a large organization with a lot of projects that are using ag grid you create a library inside of your workspace that has all of these or maybe slices or different variations of of kind of custom components that you're going to be using throughout your application to render something again maybe you're rendering some sort of inline graph like a sparkline or or whatever it is for your organization so what we want to do is we're going to create a currency renderer component that renders values and we're just going to use the angular currency pipe to do so so we're going to develop a currency renderer component that uses the currency pipe we're going to implement the ag init lifecycle method to access the cell's value via the i cell renderer perhams object we're going to implement the refresh lifecycle method i'll show you how we can return false which will allow ag grid to create and destroy the rendered component or we can use angular's change detection to handle that and we'll return true we'll register that custom component as i showed you with the framework components input binding and then we're going to use our new currency renderer so that's what we're kind of embarking on here for now let me show you the demo of that first and then we're going to get into the code oh i actually have this in chrome so if i come down to the custom components i take a look at the renderer you can see here that the total value is rendered using the currency value so if i change this we can see that it updates so now let's take a look at the code for that the first thing that we need to do as i mentioned is we're going to extend or implement the interface so this is a cell renderer so i'm going to implement the i cell renderer angular component or comp interface this extends two other interfaces that we need to quickly look at so it extends the i cell renderer and the ag framework component interface which gets the default params for a cell renderer and we can override these generics if we need to and this is what the icel renderer looks like the isl renderer requires that we have a refresh method it's going to receive a params object and it's going to return a boolean value so this gets called to basically refresh the values of the rendering of a cell we can return true and that basically signals the ag grid that we handled the change the refresh if you will if we return false then ag grid is going to do the refresh for us and the way ag grid is going to do that refresh is it's going to destroy the component and then create a new component instance probably a little bit more expensive than we need but it is an option if we don't want to deal with the refresh ourself inside of our template this is going to be pretty simple we're simply going to take a value i'm going to pipe that into the currency pipe and that's going to give us that currency formatting that we want so here's my cell renderer component again we see that i'm going to excuse me implement the i cell renderer angular comp interface i'm going to keep track of a value the ag init is a life cycle method that is required as part of the aeg framework component interface so if we come back here remember this interface also extends this ag framework component interface this requires uh or maybe does not require this has an optional ag init lifecycle method so it's similar to engine init it's just when the component has been initialized by a g grid we're going to receive a params object and that's going to be of type i cell renderer params i'm going to go ahead and keep track of that value so i'm going to set this.value equals the params value that of course inside of angular is going to trigger that value to be rendered via our template now if the values ever changed and we need to refresh that value like when i changed it to 5000 ag grid is going to invoke this refresh method for us and provide a params object that is that same icel renderer params object again we're going to return a boolean based on whether we did the refresh or not in this case i'm going to just update the value angular change detection is going to get triggered it's going to re-render the template and so i'm going to return true and say hey i got this don't worry about it i then need to register this so now that i've created my custom cell renderer component i need to go ahead and register this using the with components method on the ag grid module and i'm going to pass in an array and then here is a reference to my component now i didn't include this but it should be noted perhaps in my declarations i of course need to declare this component so that uh so that angular is aware of it the next thing we need to do is we're going to bind our framework components input property we learned this earlier to my framework components property in my class and here's my framework components property where i've registered by name my custom currency currency renderer component and here's the name that i've registered it as currency renderer and then up here in my cell renderer property i'm setting the currency renderer name that i'm going to use so if we come over to the code i kind of broke it out for you in these slides but you can reference this because we're about to get into an exercise so if you come over to components renderer if you look at render component this is the component that uses the currency renderer so you'll see this is imported up above and you'll see that i'm using it here and registering it by name if we actually go to the component you'll see all the code that i showed you before right so here's my actual component and here is my template for that component all right let's do an exercise let me go ahead and open this up for you okay so go ahead and open up that exercise we're going to be using code sandbox like i've mentioned so go ahead and open that up and follow these instructions i'll leave them on the screen for you what we're going to do is we're going to create a date renderer so very similar to what i just showed you with a currency renderer the only difference is is we're going to use the date component so just a slight variation on that but go ahead and follow along and i've got instructions for you in the component and you can use the date pipe in the template register the component we're going to define our custom framework components and then wire those up to the grid and please put any questions you've got down in the q a or if you want to raise your hand i'll be happy to let you talk to brian um and i guess while we wait let's see uh so what do you what do you do in your spare time brian we haven't really talked about that much do you have much spare time working for google i don't work for google i'm a google developer expert but i don't want to go i have my own consulting company nice but uh yeah when i'm not in front of my keyboard i like to uh do uh i recently got into mountain biking as i shared a little bit earlier yeah that i do a lot of skiing in the winter and hiking camping just enjoy being outside i imagine portland's pretty good for mountain biking there's got to be a lot of good trails in the air there's a lot of good trails there's a whole bunch of them up in the mountains and around yeah so some some good mountain biking some great hiking um my wife and i went up to olympic national park which is in washington i think it's like pretty much the most northern western part of the continental united states uh but gorgeous we did some some great hiking up there and yeah yeah my brother used to live in seattle this beautiful area up in there just across the border into bc and victoria is also a great place to go visit too yeah yeah that's cool um no real movies you have any questions anybody just raise your hand or put it in the queue i guess raise your hand if once you're done yeah you have a question put it in the q a so that way i could keep the two separate good idea yeah it's kind of a it's kind of a strange time right i mean normally you talk about movies or something i guess uh there are the the big tv shows right um well not tv shows but streaming shows um you've got you've got like the umbrella academy and the mandalorian or two of the big ones i can think of my head right now do you do much streaming yeah oh yeah i like uh we watched all the umbrella academy okay uh and uh the second series of the mandalorian came out recently i guess maybe we're a little behind sometimes i try to we try to like finish one thing before going on to the next and so uh we're starting to work our way through that so it's been good cool um [Music] what else i mean you've mentioned food a couple of times today right what's your favorite kind of food um i was saying to my wife i think last night and i said i think if i had an apartment where i lived across the street from a great thai restaurant indian restaurant and tacos i think i would not need a kitchen i could just uninstall the kitchen i'd have a little extra room in my house or my apartment or whatever because i think i could just live off of nice goes vindaloo and thai oh nice that sounds awesome sounds really awesome yeah no i like uh yeah we've got a good thai restaurant that's across the street that we like it's kind of you know we always want to try new places but when you can they're like across the street from our building and when you can just like call up and walk over in like five minutes and just pick up thai food i'm just like it's pretty easy it's tough to go someplace else it is but it's right there yeah that's true um so thai food tacos and vindaloo all sound really good and now i'm hungry like likes mostly spicy i mean i've got a buddy of mine that'll do like thai hot no way i would be crying like i would be chugging milk so are you talking are we talking jalapeno a little bit hotter than jalapeno i'll do the jalapeno for sure like yeah like a raw jalapeno on like a taco or something or yeah yeah i mean i won't eat it straight but habanero they're the taco place across the street as well they have a habanero sauce it's like i'm a glutton for punishment like every time i think about two-thirds of the way through i'm just like too much habanero sauce and my wife is like you're never gonna learn i think the first time i got it like i got the big size and i took my taco just dunked it into the whole like and took like three bites and i was like oh boy oh yeah i know that feeling gonna need some yogurt or something definitely coat your mouth uh coat your tongue and like something dairy related yeah not water water does not do much for you no it actually makes it worse water and soda are a bad idea there's a uh speaking of streaming isn't it there's like a youtube channel where this guy eats really hot chicken wings with like celebrities have you ever oh yeah oh yeah what's it called um hot ones hot ones yeah that came right up yeah yeah yes yes very good the best episode i watched was with shaq like he was like you're not you're not going to get me right yeah at one point like the gallon of milk was sitting next to him and he's just like [Laughter] that was such a good one i was like oh my gosh and shaq's awesome but that was a great episode so shaq did that one chip challenge also on espn right where he ate the chips see that oh you can find it on youtube i'll have to check it out but yeah we we had a guy do the one chip challenge during stand up one day on camera that was pretty funny what is the one chip challenge it's a box that's got one chip in it and i think it's ghost pepper um and so the guy the guy that did it during stand up said that it hits you really hard at first but then it's gone um so he's like if you can make it through that pain yeah yeah now we're getting recommendations of shia labeouf and dj khaled yeah yeah dj khaled uh i forgot to give a time shoot uh we've got one hand up okay give me a hands up if you made it through the exercise for the date renderer four all right six seven eight nine nice all right let me get this up for me so we're going to walk through this together date cell so i guess while he's doing that i mean people are giving hot ones recommendations mine is alton brown i loved i loved his show on food network and his hot ones episode is awesome that's cool all right if you finish the exercise give me a yeah raise your hand let me know that you're done i don't want about 15 now 16. 17. okay cleans the wings there's a good point to that matt right i mean like i think at some point like i think i've only ever seen the shack one but i think he takes like one bite and he's like that he's like like done it's like no come on man you gotta finish that thing dude some people can eat hot food like that oh what's the name of the guy that does hot ones i watched an interview with him i don't know and he said that the thing that people don't realize is that he's eating the wings along with everybody else so he's eating so many of these hot wings so i just thought that was yeah chris evans that's right champion looks like here's our state renderer here's our template here's our module here's our component all right i'm going to go ahead and get started with the exercise if you've completed it go ahead raise your hand but let's go through it together okay so we're going to open the date render component and the first thing i need to do is i need to implement the i cell renderer angular comp interface so i'm going to implement high cell renderer angular comp interface and immediately you could see that excuse me that my code is not right i got an error it's saying i'm missing the following properties from this type from this interface refresh and ag init so i got to go ahead and do that so i've already got my cell value up here so what i need to do is i'm going to do an agnet method and ag init is going to get called with the params object and the params object is of type i cell renderer params and i'm going to go ahead and set my value equals to the equal to the params dot value property and then in the refresh method i need to return a boolean the first what i'm going to do is i'm just going to return false and i'm going to let ag grid refresh the component and again it's going to destroy and recreate the component but we should see in our in our grid that the value does change let's come over to our template let's do value and i'm going to pipe this to the currency pipe i need to register this inside of my ag grid module with components so i'm going to register the date renderer component here and i need to also declare it okay and then i need to come over to my app component and i'm going to use my custom date renderer here the first thing i need to do is i need to keep track of these components i'm going to call this framework components and i'm going to be it's going to be an object and i'm going to call this just the date renderer and this is going to be the date renderer component that i've imported up above and then here i'm going to use the cell renderer why is it oh it wants a comma there right and then i'm going to give it the name of date renderer i don't want to semicolon there and then need to come into my template and i need to oh i already did that for us so we already have the framework components bound in so let's go ahead and open up our component it's taking a while hmm sometimes code sandbox i can hear my fan is spinning uh what we got is not a number what did i miss here oh uh i didn't want to put it here i want it on the currency oh i apologize this is supposed to be the total column let's get rid of this it's not going to like this this is supposed to be the total not the date of order that's a bug go ahead and file a pr uh or no this is supposed to be wait why did i call it oh right sorry i'm getting confused my apologies date of order i use the currency pipe this is supposed to be the day pipe duh let's see if that works yep wrong pipe thanks guys sorry but thank you everybody oh and here is my sandbox crashing i went all morning without it crashing let's see all right yay so there's our date renderer let's see i could do long so now i could do this of course if i wanted to you know make this a really usable date render component i probably could have an additional param into my component where the user could specify the format so that would be a nice improvement on this okay next let's go into the floating filter so floating filters extend the functionality of an underlying filter so when we configure ag grid we can set a filter and then we can enable a floating filter as if we want to which will be in the additional row that's below the header row we can create custom floating filters using angular and creating components that are going to get rendered in that spot where the floating filter goes what we'll do is we'll use an on parent model changed method in our component and that on parent model change method is going to get invoked by ag grid and it notifies the my floating filter of the parent filter model change event because remember it's extending it right so we've got the filter that's just the default let me go over to here and if we just look at one of our filtering examples right this is the actual filter when we add the floating filter that goes down below this filter the floating filter will be here and that actually extends the filter and so if the user changes the value in the parent filter we need to have a way to notify the child component if you will the floating filter that that model has changed and so we're going to be implementing this method as part of this exercise so what we want to do is we're going to create a floating filter component that uses the material slider for filtering number of values so i'm going to create this component i'm going to use the matte slider component uh i'm going to define some custom params this time so rather than just having the the default parameters like we used before i'm going to create an interface that has some custom parameters for passing the parameters to the filter and i could pass those values down in my column definition object so i can customize the filter if i want i'm going to implement the method that i talked about previously the on parent model changed lifecycle method i'm going to use the input output binding yeah it's a bit confusing so on matte slider the name of the binding that actually sends the value out of the mat slider is called input i'm not sure why and then we're going to invoke the on floating filter change method on the number filter instance to filter a column then we're going to go through the usual steps that we've been doing all along in terms of registering that filter let me show you the demo of what this is going to look like before we actually build it okay so here's my demo and here's my slider so you can see over here that i'm sliding this up and as i slide it up and up and up the max value that i have is 5000 as i bring this down it's filtering my totals for my orders so i'm not sure if the use case is ideal for this i don't know why you'd want to necessarily look for orders this way but perhaps you do and so this is one way that we can kind of this is a matte slider in a custom angular component in a floating filter i also have a date of order and i like this one so right so this is uh now this is using angular materials uh date right so rather than using the built-in uh date filter that comes with ag grid if i want to i can use the a custom component to do so so let's target this 11 11 2019 so i can go 2019 november 11th and now i just see all the orders that were placed on that day so this is another great example of using a custom component for a floating filter and all of this code is located in this component so if you go to shared components i've got the slider filter in there and then i also have the date filter let's go ahead and walk through the code so the first thing that we're going to do is we're going to implement our interface again this is kind of the first step that i like to do so that way i know that i'm meeting the code contract so i'm going to implement the i floating filter comp interface which extends i floating filter and then it extends the framework component and this time the generic is the i floating filter params this is what the ifload and filter code contract or interface looks like and there's that on parent model change method that i must so it's required so i have to define this method it's going to receive the parent model along with a filter changed event in returns void again ag framework component this is the interface for a component there's your generic t and here is the ag init lifecycle method and the params object of type t here's what my matte slider is going to look like i'm going to use the material slider so if you're not using angular material you can go to the docs and look at it if you'd like but basically i'm going to have a max and min value that i'm going to bind into that i'm going to let the user and what i mean by users like the user of my component set this so i'm going to have some additional filter params where you could set the min and max based on what you want here's the value that we're going to set for the the current value of the slider and then here's that input binding it's an output event emitter called input which is weird and i'm going to call on input and get the event object okay here is my custom params interface that i've mentioned so i'm going to define a new interface called slider filter params and then i'm going to extend the eye floating filter params so those eye floating filter params are the default parameters that you can pass to any floating filter in at grid and i'm going to add these two additional properties max and min so now that we've kind of taken a look at those interfaces let's get started with the actual filter component itself so i'm going to implement the interfaces just like we talked about so eye floating filter and ag framework component notice i didn't actually extend eye floating filter component this is because i wanted to override this generic t right i wanted to specify my own params object so that's why i have to implement both of these and this gives me the opportunity to provide my own custom params interface or signature i'm going to go ahead and keep track of that min and max value i have the initial value of the slider and then i'm going to keep track of the params that are passed to the slider so just a couple properties in my class when the component is initialized by ag grid it's going to the ag init lifecycle method is invoked and i get my params that are of my interface that slider filter params that i defined i'm going to keep a reference to the params object and i'm going to set the max and man based on whatever the user specified when they're using or implementing the s this filter in their column definition here's that required method the on parent model changed and i'm going to get the parent model in this instance the parent model is a number filter model because i'm building a slider filter that is going to extend the functionality of the default number filter as long as i've got a parent model value i want to update my value with whatever the user entered in into the that menu option in ag grid otherwise i'm just going to go with a default value of 0. here's my method whenever the slider is changed so it receives the event object which is of type matte slider change i'm going to plug off the value and i'm going to store that and then this is where i need to notify the parent filter that something has changed in the child floating filter so on the params object so on the i floating filter params interface i've got a parent filter instance i'm going to invoke that instance with a callback function so if you're using the data source and you remember from when we did the data source this morning with the infinite row model that this should look this kind of callback signature should look familiar so i'm going to get an instance of my parent number filter and then on that instance i'm going to notify it that we've had a value change so i'm going to invoke on floating filter changed and then i need to specify kind of these are different for every filter type that you're using so if you're building a filter component that extends the date filter then you're going to have maybe some different signature here but i'm going to say choose any value that's greater than the value that the user is selected or the value that they've selected because of the slider okay this should look familiar we're going to register our component using the ag grid module with component static method and then here's where i'm actually going to use my filter component so the filter you'll notice is the default built-in ag number column filter and i'm allowing the greater than filter params that option in the drop down and only that option and then here's where we bring in our custom component so i'm going to set up the floating filter to be true i'm going to bring in my custom component remember we register by name so that's a string and then here's my floating filter component params object so i could pass in this for example suppress filter button is built into any floating filter and so i can use that parameter as well as any custom parameters for my specific component again we're going to go ahead and register our components so here i'm registering a couple of components by name and then i'll need to register those with the specific ag grid angular component so that way it knows about the components that i have available so this should say exercise so what i want to do is so i did a slider what i want you to do is i want you to do that date filter and you can use if you get stuck or you have any problems you can use the date filter component that i wrote remember back here i had the date filter and this is using aeg grid so i've got a solution for you of course try to do the exercise if you can without the solution well why don't you go ahead and build out a custom floating filler component that uses materials datepicker this is a nice ui so you're going to open this component follow some instructions excuse me talking all day uh you're going to open this module we need to do our registration as we're used to we got to define the custom framework components add that in a lot of what i just showed you with the floating filter for the slider so kind of very similar flow to what i just did the only difference is you're going to be using the material day picker and if i go over to the code sandbox i'm going to close that tab my fan is computer is going to start melting um let me open this up yeah sometimes just doesn't like it so if we go over to the date filter i already wrote the material code for you the goal of this exercise is not to learn how to write a material day picker so i've already got the date picker here for you um and you should see that here's the date control so i've already got the form control wired up for you so you should be able to don't worry about the actual material side of things you got a form control that you can use the value changes observable on and we can subscribe to that value changes observable and get access to the the date value so like any good instructor i've got a solution file just in case we get stuck so we can key on the important learning points not get stuck in the weeds here okay so i've got my date control i've got my input disabled i'm also going to need to keep track of the params so i probably should have done that and it did kind of hint to that here but let's go ahead and keep track of those params so i'm going to do a private variable called params and this is going to be the date filter params and it looks like i need to bring those in is that not where's date filter perhaps oh right i need to actually define my deep filter param stuff sorry i apologize i need to follow my own instructions so let's just create an interface let's call this date filter params and we're going to extend the i floating filter params and we're going to have an input disabled property that's of type boolean so that way we can disable if we'd like to and then here's my date filter params i'm going to create an a g init lifecycle method so agnit and in here we're going to keep track of our params so this was called with our params object which is a date filter params and i'm going to set that and i'm also going to set the input disabled property so i'm going to do this dot input disabled equals params.input disabled now let's come down into the engion and knit lifecycle method and we want to subscribe to the value changes observable excuse me on the day control so up here i've got my day control that's a form control and i see here that i've got a subscription so i'm probably going to use that to track my subscription and uh looks like i've got an ng on destroy already that's going to unsubscribe from my subscription so let's do this dot subscription equals and then we're going to do this date control that value changes and on the value changes observable i'm going to subscribe and i'm going to get the value just to make sure i'm doing this right yes and now that i've got the value what i'm going to do is i'm going to remember we've got this parent filter instance and we get a call but we're going to give it a callback method and we're going to get the date filter itself and so in when the value subscribes here i'm going to do this.params and i'm going to get the parent filter instance i'm going to invoke that with a callback that's going to receive an instance of the date filter and then inside of here i'm going to do on the instance i'm going to invoke on floating filter changed and then i'm going to provide that with some values so if i look at this on floating filter value change it what's a type and a value and if i look at the date filter let's see are they going to provide it for me there's the date filter model set params where is the it must be farther up um but we know that we've got the type so we're going to set this type i'm going to say give me just dates that equal so if you look in the documentation for the date filter there's a bunch of different types right just like the number filter has like equal greater than less than um all the options that kind of show up for a particular filter so i'm only going to look for dates that have a particular value and then i'm going to get this date value let me call this date up here and this is actually going to be a javascript date that's coming out of angular material and it's possible that somebody didn't select a date so this could be a null value as well so what i want to do is i want to say okay well if i've got a date then let's go ahead and set that date in in order to do the filter change we actually need to provide a specific format so i'm going to use the format function from date fns that i've brought in i'm going to format the date accordingly so i need to do a year a month and a day otherwise let's just set it to null so that's my ng on init method and then i also need to define this required on parent model change method and remember this is when the parent model so the filter up above the floating filter when that value is changed i'm going to get notified as the child if you will that something has changed and so i'm going to get a parent model instance and that parent model is going to be the date filter model and you can get you know in here is where you've got this kind of some of the typing around this for the date filter model and now that i've got the date filter model i'm going to check for a value i'm going to say okay if the parent model has a value on it or if it's not you know if it's a truthy then i need to again i'm kind of have to do a little bit of parsing this is specific around dates between whatever the you know i'm using angular material so between that and going into the floating filter so again i'm going to use that date parse from i'm going to use parse from date fns and i'm basically going to get the date that the user entered so i'm going to do parent model and i'm going to get the the date that they entered and then i'm going to tell it that i know that this comes in as a specific value and you can see here i said use the parse function and then we're going to use this string as the par string because this is what the value the parent model date from format is otherwise just use a new date of today if i don't get a parent model value i'm just going to do i'm going to reset the day control to uh nothing just uh give me one sec i'm just gonna set that value to an empty string okay all right so now that i've set that value oh i didn't actually set the date here so then i'm going to do this.datecontrol i'm going to set the value and then into the date control itself this is now going into the date control that is my my form control for my my material input again i've got to do some formatting so i'm going to do i'm going to format it using iso and i'm going to provide that date and then i don't want to emit any events out of this set value so that way we don't get any sort of triggering or recursion or anything so we're going to set emit event to false okay so that was kind of the first step next thing i need to do is kind of do our registration so i've got this all here uh hopefully [Music] oh i never actually extended up here i should have implemented these let's do that just to make sure we got everything right so i need to implement the eye floating filter and i'm also going to rather than there's also i think another class like a you know eye floating or eye floating filter angular comp or something like that and that just extends these interfaces but i'm going to extend these myself rather than using that so that way i get an opportunity to specify that generic like we did before so now i'm going to do a g framework component and i'm going to specify the params object and i've got my custom date filter params object and what do we got here ag and knit is missing oh here we go ag in it good good good i'm glad i did that so now we are meeting that code contract good let's close that this was all done for us i don't think we need to do any styles we need to come over into here i've got my date filter component there but i also need to define it in my agreement module and then over here i've got my framework components i need to come down into my framework components i set this to a string and i'm probably just going to call this date filter let me see what did i call it before yeah i just called it tape filter tape filter and this is my date filter component all right and now i can use that date filter in my date of order so i've got my floating filter here and so now i want to say floating filter is it floating filter component yes it is and i'm going to say the floating filter component is the date filter all right let's save that i got all of that done i think we're good i registered it we implemented our interfaces we're getting the prams we're setting that that looks good let's give it a try let's see what happens uh good eye on the on and it to a g in it there i certainly just kind of typed that pretty fast so here is my filter see if it works let's go to 2019 november 11th and there we go indeed it works and then i should be able to test this kind of going on a limb here but if i change this and let's just change this to like the 15th notice that this changed right there right so that's that on parent model changed of that got triggered right so now when i change the value in the parent component or the parent filter i'm changing that value down into my custom filter so it knows about it and so now that got updated with the right value and i can see the 15 is selected all right do you have any questions throw those in the q a otherwise we'll keep moving along the next one we're going to look at is the header component so we could define a custom header per column or we could define a custom header for all columns and what we want to do is we're going to build a custom header that uses material icons for sorting so for whatever reason we don't want to use the material grid theme i want to write my own header this is what ux my ux team has told me to do and so i need to implement a custom header for my grid that uses these icons so we're going to create a new component that uses the icons to display links for sorting the grid as almost always we're going to implement the agnet lifecycle method to access the column's display name as well as the enable sorting property and we're going to use that to determine whether sorting is enabled or not on that column we're also going to use is sort ascending is sort of descending is sort of none methods that are exposed in the column property of the i header params object that i'm given to determine the current sorting state of a column then we're going to use the set sort method to update the current sorting of the grid based on what the user clicks on in the header and finally we also need to register our component the only change here when it comes to registering a header for use in our grid is we actually need to register it with a special name so we can't just call it when we do framework components we can't just call it header my header sum header i actually have to use this a g column header name and this is a special you know they prefix it with a g in theory you're not going to use that prefix and this is where i can register a custom header component for all the columns and so that is something that we're going to be doing let me show you the demo for this uh so i think what i'm going to do we've got 24 minutes remaining i may skip just so everybody knows i may skip the uh exercise for this so we can get to the editor but i want to walk you through what this header looks like and so that way you have kind of an understanding is if you need to build a custom header component this is how you're going to do it so here's my header and these are my matte icons and i can clear the sorting if i want and what the exercise would have had you do and if you want to do this on your own again i put that the pdf remember i gave you guys a copy of that so what i was going to have you do is another responsibility of yours as an implementer of a custom header component is you got to implement the menu right so if there's a filter on this column there should be a little icon that shows up with a menu link that opens the menu to filter right i mean if i come back to our filter i'm talking about this little doohickey right so you can see that i did not do that in this header component um and that's something that the exercise has you do so if after we go through this and you want to get a little hands-on with a header component feel free to do the exercise but for the sake of brevity i'm going to skip that but i do want to show you the header component right so i've got my up my down my clear sort i also know whether it's sorted or not based on the params so we're going to start by using this i header angular component and this is starting to look familiar i've got an i header interface here's my ag framework component and then i've got an i header params generic that i specify for that or this is written for this is already defined for us if we need to override the params then we would implement these two interfaces ourself here's what the i header interface looks like there is a refresh method that is required and this gets the header to refresh so it gets called whenever the column definitions are updated so that you know to re-render the header here's what my template looks like i basically i wanted to wrap things in a header div i think i did some flexbox styling i'm going to display the name of the header name if you will and then if sorting is enabled then i'm going to display some links to do the sorting and i will i'm going to know if sorting is enabled or disabled based on what you know the user the person using my component specifies in the column definition if sortable is false then i don't want to display these sorting links i don't spend too much time looking at these but basically i've got a bunch of links i could have used buttons not sure why i chose an anchor tag but basically if i'm sorting descending i want to toggle that arrow from like up to down so if we come back here oops so i want to kind of just toggle these i'm just using ngif basically to change the display of that so if i'm going descending or if it's none that's kind of my default then i'm going to have this material icon and i'm going to call on sort and say that i want to sort ascending the next one should look very familiar it's just the inverse if it's sort of descending then we're going to invoke unsort with descending and this is the cancel button and i'm just going to send in an empty string to clear the sorting i've got some properties to track things like the name whether it's enabled and there's my params object that i get in my ag init method speaking of which there's my ag init method there's my params object that i get i'm going to store off those params so i can use those in the template and i'm going to keep track of the params object itself so i have it down the road here's my refresh method remember this is required by the i header by the i header interface and here i'm going to update the header params and such because the the column definition object has changed uh again we saw this previously i could just return false and ag grid would just destroy this component and recreate it if i don't want to deal with this refresh but i'm using angular i've got change detection i'm good to go i'm just going to return true and tell a g grid hey i'll take care of refreshing the header when necessary here are some methods i basically just got a couple of helper methods i probably could have just used the params object directly in the template um maybe just to make the template a little shorter i just got some some methods here that are using the column object that is part of the params object and i'm just checking the sorting whether it's ascending descending or set to none and then here's my onsort i'm going to get on sort i'm going to specify a string ascending descending or nothing there's my mouse event and then i'm going to invoke the set sort method on our params object give it a direction and i believe this uh event.shift key i'd have to double check the docs but i think this has to do with the multi-column sort okay and of course we need to register it and we need to register it note here that i use this special name remember i said i can't just call this anything when i register by name i've got to use agcom header and this tells ag grid that i want to use a custom header component and of course we bind that down into a g grid angular and set the framework components here's the exercise i'll throw a link in the chat if you are up for it or if you want to keep the link and try it um again what i wanted to have you do in this exercise was um i'm just afraid that we may run out of time um let me see uh what do you think jason i've got one more component that i want to get to we've got a half hour left oh you know what i want to stop and do it or should we just keep going let's let's leave it to the attendees raise your hand if you guys want to do the exercise and leave it down if you wanted to continue on sure well he says continue i'm getting a lot of continues yeah we got i figured as much that's what i was thinking let's just um do you want to answer this question really quick before you move on oh sure uh sorry if this went over my head put and no you don't need to apologize that it's all good what's a use case for having the parent filter and the floating filter and connecting them good question uh the use case is just for it's just a ui benefit it's just a kind of a short um a short way to to have the fill the date filter right there so it's just a just an ability to have that and the the fact that it extends it is how all floating filters work um we can you can write a custom filter itself and not use a floating filter if you want to i just chose to do a floating filter so it seems like you'd only want your custom ones shown and not worry about implementing unbearable yeah sure um yeah if you're not using the floating filter functionality then you would just create a new date filter component that's not a floating filter and then you don't have to worry about notifying or the parent changing and stuff so this was just i chose to do a floating filter that's really the end result is you know if that's let's say that's what uh the task was you know then that's what we would do but you can definitely write a custom filter and use something like material or whatever uh alex says continue i want to see the styles even with the skin through yeah we might be able to do that actually alex so i think let's this exercise is a good one uh i suggest you grab the pdf i'll put a link in at the end of the day here um you know spend a couple minutes and and give it a shot um and let me do this for you as well i don't have an actual solution so for those of you that want to do the exercise here is can i just copy sandbox link here is a link to the solution so if you get stuck on the exercise there's grab that link in the chat and you can use that if you get stuck you need to look at the solution that's the solution that i wrote for the exercise okay let's do a day editor this is a beautiful like old church from the 1200s or something in scotland anyways okay so date editor i'm going to show you a demo first so here's my date editor and here if i double click on this i'm going to open up my material like date filter right or not date filter but date picker and you'll see that i had to do a little bit of work to get it to like trigger immediately so it didn't just like show an input and then let's just change it to the first so now it's the first let's change it to december 31st now it's december 31st so this is a nice uh much better ui than because otherwise i don't think that um here you can kind of see it gets it doesn't like it if you don't choose a value um otherwise there's i think the date the there is a date uh i think isn't there a date editor correct me if i'm wrong i think there's a date editor that's built in or maybe it's enterprise only i don't know um but this is another uh you know solution for building a date editor so let's take a look at the code you're gonna see a lot of repetition here and this is a good thing uh certainly when we're learning stuff but we're going to see we've got an l i cell editor angular component interface it's going to extend isel editor and it's going to extend a g frame or component and there's the iselle editor param so starting to look really familiar and that's a good thing here's my else i cell editor i need to i'm required to write a method called get value and what's going to happen is i'm going to tell ag grid when i'm done editing right so it's going to start editing i get to do whatever i want in terms of this interface or however i want to edit right and then i'm going to basically through the params object i'm going to say hey i'm all done you know the user is all done editing the cell and then it's going to go and invoke this get value and get the value to actually store as the value inside of that cell and of course that value could then go through its usual process with a cell formatter and a cell renderer i'm going to use a the material day picker as we saw i think i needed to put no i don't know if i no it's not here um here's just your form control i'm going to use that to get the value changes so here's my my form control for my date picker um right this is what i needed to do so in order to get the date picker to launch right away into that um to have it show right away so as soon as i start editing immediately i wanted it to kind of trigger the event of showing the day picker and not just show an input element or something so i needed to use the view child query here and get access to the actual date picker component and this static true is no longer required if you're doing angular version nine and higher i think so my date picker property is a matte date picker class instance so it's a little nuanced there but i just want to tell you that's why i had to do this in this particular case all right like we've done before we are going to implement my my uh i cell editor angular comp notice i'm not doing the uh i editor or whatever it was because in this case i'm not providing any custom params interface so i can just go with the default and here is my params going to store that i got an arcgis subscription to deal with unsubscribing and then here's the value which is a date object that comes out of the date picker again here's our agent lifecycle method should look familiar there's my params i'm going to store my params and then i'm going to set value on the date control on my form control and provide the value and then i don't want to admit an event that the value has changed so i'm going to use the options argument and set event emit event to false so this is going to update the date control with the value from ag grid so whatever the value is this is going to set it into my date picker so that way when i double click this it's got december 31st selected i need to know about that value so that way i can kind of choose the right value to display set the value down into my day picker and then here's my ng on init lifecycle method this is where we're going to start we're going to use the value changes observable and subscribe to it and if we get an error looks like here i just chose to log out an error a next notification i'm going to get that value and i'm going to set the value to the value property inside of my component and then here's we remember i'm rem i was saying we need to tell ag grid that i'm done right and so what i want to do is in this particular use case as soon as you select a date in the date picker i'm good i don't want to do anything else so i'm going to tell ag grid hey stop editing right and stop editing is going to trigger ag grid to kind of do a whole bunch of things you know kind of like you know get rid of the editing event or whatever and kind of display it invokes get value on my component and then it puts that value inside of that cell i've got a couple here's that that little bit of i wouldn't call it a hack by any means but here's that a little bit of nuance where i needed to use the after view init lifecycle method at angular to basically open the date picker initially i'm cleaning up my subscription and then here's my required get value and i'm just returning this.value and there it is i don't know why i had it in there twice here we go we're going to register so we're going to register our component and here we register our component just like we've been doing all along i'm going to go into my actual component that's going to use my date picker and i'm going to register it with the framework components here by name there's a reference to my date editor component and then for the cell editor i'm going to set that equal to that name of date editor and of course we bind that down into the ag grid angular component we've got 20 minutes left this exercise is a good one but we also have an opportunity to take a look at some of the styling and i was a little i kind of had a feeling that the component exercises were going to take some time uh let's see jason what are we thinking do you should we should we do the exercise i again let's put it up to a vote what other people's want yeah raise your hand if you if you want to do this exercise um if you want him to continue on to styling go ahead and a lot of people are saying continue and styles in the chat um so um i guess at this at this point in time before we continue on i want to give anybody who does have questions some chances to ask any questions um about the editor component all right looks like we're continuing cool yeah it gets to be a little repetitive there i know but i think it is it's not a bad thing certainly when you're learning it's like okay i do this i do this i do this but you can see how they i like that it's also if you will when i'm building diff these different custom components i don't have to reinvent the wheel i usually know okay i'm gonna have to enter do an interface some require this method some require that method you know i'm almost always gonna use ag init um and then and go from there all right let's back up to the styling okay um we've got about 15 minutes and i want to respect everybody's time but i want to give you a quick snapshot of styling with ag grid and i'm going to skip around a little bit just so i can give you a high level overview um the best that i can in the time that we have remaining there's a couple of things that we should know is when it comes to styling and agreed there's different levels of styling and so all the way down at the very the smallest level this is very similar to like css or right so we've got inline styles on an html element right has the highest specificity is directly on the element probably not great in terms of reusability probably not recommended for an entire application to use just inline styling i mean i wouldn't recommend it i don't think it's probably the way to go if that's what you're doing that you know that's you can certainly do that um but similarly ag grid has different levels so i can style things at a cell level i could style at a row level i could style at a grid level and within each of those levels i can style using like an inline style tag so i can say on this cell i want or on every cell i want this style or every cell in this column i want this style i can also put a class right so i could kind of bring it up a little bit of a level and say okay i want to put a class on every cell in this column i can also dynamically add and remove classes so i can use the cell class property that'll dynamically add classes i can also use the cell class rules property to dynamically add and remove and it's i want to hit on this because if you start to get into styling this you might get kind of tripped up on this and this also applies to styling of rows so if i want to kind of toggle a style on a row i have to use this either row class rules or cell class rules property on my column definition or wherever it's either com definition or for rows for rows i think it goes on the actual ag angular or ag grid angular component but the cell class rules is an object akin to like ng class where you have an object with a class and then like a predicate function that gets invoked and determines and that predicate function whether it's true or false will add or remove either the style or the class and so if you're using just cell class it only ever adds classes and never removes classes and the same applies to rows so here is an example of my cell styling where i'm literally saying on every cell in this column add these styles not very reusable a little bit of a blunt force method but it's something i can do i can also give an array of cell classes to apply to all of these cells in a column and i can also have a predicate function that returns a class or an array of classes that are added to the cells and never removed once it gets an error class there's no you can't take it off unless you use cell class rules so here is where we would use cell class rules and we're going to say i want to have either either a negative or positive class on it based on that value and so this will add and remove this based on the boolean value that's returned from this predicate function same is true for the positive class it'll be added or removed again just to kind of hit that home if i use cell class and i add one of these classes it's never removed because that's just the way cell class behaves and that also applies to rows uh i'm not sure what i was going to do here so we could take a look at a demo real quick so if we go into styling and cells here's i'm styling all of these cells and then this is using the cell class rules so i don't remember if i go negative maybe yeah so i'm adding and removing a class on this element so if i come over to my dom inspector i should see this cell class negative on there and then don't move around too much on me and then if i put this to a hundred we can see that the cell class negative class was removed and the cell excuse me cell value negative was removed until value positive was added if i'm not using if i'm just using the cell class or the cell style remember that's that's not the case uh i've got an exercise for you if you want to go through this later similarly rows have a very similar functionality is a beautiful picture of the alps by the way i took last fall hiking so i can also put styles on a row again it's kind of that blunt force methodology row style give it an object i can also have a callback function that will conditionally apply styles using the get row style callback function or i can have a row class that sets classes for all of the rows i can have a get row class callback to conditionally add classes but not remove and then i can use the row class rules to add and remove classes conditionally so here's some of these different methods here's my get row class kind of callback method i could just hard code a row class if i want to or an array of row classes i can have some rules that's that object that has the classes the key the values of predicate function to conditionally add and remove class rules and then there's that blunt force methodology where i just say hey i want all the rows to look like this here's that row class rules object i've got those class names as properties and the value of the property is a predicate function that's going to add or remove class and then here's that get row class where i'm going to also kind of do some logic and return a class that's applied we can also style um uh let's see row styling demo got 10 minutes left okay uh i don't remember what was in my row styling demo uh let's skip this and get into the theme stuff i'll just make it easier i mentioned this maybe this morning um but basically i've got several themes that i can use with ag grid there's the ball and themes the most dense alpine a nice modern and but less dense theme material used in material spec least dense and both balm and alpine come with dark mode options but here's what i want to teach you is i want to teach you real quick about customizing themes i want to show you that there's a couple cool things that we can do with themes so using a couple of different things first i can use theme parameters so with scss rather than just including the theme straight out of like the disk directory of the node modules folder i can actually include a mix in and i could customize the look and feel based on some theme parameters and i'll show you what those look like i can also use css variables to customize primarily the color of things in the grid foreground color background color border color i believe i can also use css rules to target things like even rows odd rows and then finally there's also additional mixins and functions that are provided by ag grid to get access to some of the computed values like um like colors and some other things i'll show you these real quickly in a couple minutes we have left so here you can see first of all that i'm not using the css file anymore i'm bringing in this ag grid scss file and then i'm bringing in this ag theme alpine mixin and then i'm going to define the aeg theme alpine class and then i'm going to include the aeg theme alpine mixin right so you kind of think of this as like this is how they're generating the theme like when you use just the css file they're basically doing this for you and and dumped out the css but what i could do is i can use some parameters into this mix-in and i can override some parameters and these parameters kind of almost like css like cascade down right and so if i don't want any borders on my grid on my cells on my rows i can just set borders to false or if i want the alpine active color so like when i select a row that's like a what's called like an active state i can set that to deep pink if i want i can change the padding throughout the entire grid by just setting grid size so i maybe alpine i like it but it's a little like it's not quite dense enough for me or maybe i want a little more spacing i can modify the basically like a factor of spacing throughout the entire application i can also use css variables for example i can set background color foreground color and border color and override those that are defined in my my css and so these will actually override because i think they're using css variables for these um so you can override in a particular use case or maybe in a row or something like this where you want to change the colors and then i can also just target some of the css rules and so i could target the header for example and you can find these mostly just by inspecting the elements in a g grid and say oh a g header perfect or row even perfect or a g row great i want to style all the rows this way um that's one way to do it as well and what i want to show you is i can actually use kind of grab computed values so i can grab that parameter that was provided to the mixin and get the background color if i want and and this will get just the value or i can include a mixin that they've given me called ag color property and i'm going to use the alpine active color value to set the border bottom color css selector or or whatever property i guess yeah attribute not sure uh so that's kind of a high level overview of theming and customizing the grid so there's a documentation of course on ag grid's website where you can get more information about what are all the parameters what are they don't actually have great documentation in my opinion around the css variables i kind of had to dig into their source code to look at some of that um uh here's another one um i'm doing agro even here and and setting that there's some more examples yeah so that's kind of i even went a little fast on that so that's kind of a high level overview of the styling i've got a bunch of demos you can take a look at so if you actually go in the application to the styles.scss file so what you want to do is just comment these out uh let's just do it let's comment those out we're going to bring this in and let's change this it's kind of hard to see let's change this to deep pink i've got a grid size of four pixels let's save that see what see what happens yeah i did something wrong oh don't i still need one of these i don't remember let's see um [Music] what am i doing wrong here oh this is the ball theme that's why we need to find one with alpine looks like in the editor component so components editor editor there we go so now there's my custom theme with my blanched almond my my deep pink uh you know if i kind of you can see that it's bringing in some of these i can increase the entire size of the grid so let's say six pixels we should see kind of all the spacing increase there it goes i think that's kind of the default for alpine or if i really need more spacing you can do that kind of use that so certainly a lot of tools that they provide out of the box in order to customize the look and feel there's a couple of no-no's don't do anything that changes positions when it comes to doing almost any styling in your grid ag grid one of the reasons why it's performant or one of the techniques that they use is you'll notice like this isn't just a table underneath the hood right and they're doing some pretty complex um like transforms if you get in here i think maybe like on the row and stuff they've got like transforms and all this kind of stuff so if you start messing with positioning um you can certainly use display so if you want to do like display flex flex direction row or column you know maybe you want to display a bunch of stuff in a column for this particular like column for customer name you know you want to have you know last name first name or you can do that but i'm pretty sure like one of the big no-nos and gotchas is like don't start doing like positioning absolute or relative or anything like that because ag grid you're gonna start to see uh it's not gonna it's not gonna work you're gonna get some weird behavior um and they've they've got some good docs around this so if you come into into themes they'll talk about some of the the different things that you can do and customizing the theme and if you come down into there's a there's a section in here on the docs where they basically say don't don't mess with certain stuff i think here so avoid breaking so don't mess with position overflow and pointer events basically a may break functionality so that's kind of a warning okay cool i'm going to end there we got one minute left a real quick let me give you my last slide thanks for those of you that are sticking it out here towards the end i certainly hope this has been incredibly valuable for you as i mentioned in the beginning and if you were a little late i started a kind of a really cool initiative to make it easy for people to learn in public i'm a strong advocate for learning in public and i created a website called lookout.dev it makes it real easy to go and share something that you learned so for example if you know oh we got a couple more so alex akrushko works at google uh for the firebase team this is really cool he shared this today and he talked about how he can get better typing when extracting the keys and entries from an object or enum with typescript so you can see that he kind of did an overview and then we've got some code examples here and then you can always add a comment so it's a really cool way to just kind of share what you learn and and learn in public i think there's a couple more that i've written in here that might have like some do's and don'ts here's an example of like using an svg for favicon i didn't learn this i know it sounds crazy until like this summer at a conference called cascade.js and so i talk about you know kind of what it is a little description about what i learned i've got some instructions on what to do and maybe what to consider you can also add y and avoid and then i've got a code example say hey if you're using a favicon just use an svg and don't do what i used to do which was i used to use sketch to output like eight different sizes for mobile and tablet and desktop and iphone and ios and all of this crazy stuff and so i learned that and so i wrote a quick look out and shared that with everybody and so it's a great way to kind of learn in public so it's free to join check it out uh join us uh i would love to see what you come up with and what you share with people and i certainly encourage you to learn in public i think it has some really unique advantages to just being able to learn of course but also to contribute back to the community to engage and to be a part of kind of the developer ecosystem and with that that's my plug if you will uh i'm not making any money off it's just something i'm passionate about uh i want to say thank you enjoy the rest of the conference if you're doing workshops tomorrow or the conference on thursday and friday have a great time thank you so much if you want uh you can follow me on twitter my twitter handle is brian underscore love my dms are open if you have any questions about ag grid you can ping me i also have my own consulting company so if you need some help with an angular project react node these kinds of things gatsby happy to get engaged with you on that and uh thanks again i'm going to put real quick before i forget i'm going to grab one more time a link to the pdf for those of you that maybe missed it so that way if you want to do some of the exercises uh drive well brian's doing that i want to take the the time to thank all of you guys for attending um these conferences and workshops only happen because you guys are willing to attend and spend your time with us um i really want to thank brian it's been really enjoyable spending the day with him today um he's presented some really good information on a.g grid i've really enjoyed it um and then uh just just so you guys are aware um you guys will get a link um that will be available for seven days that will give you the ability to um re-watch um the sessions that you've attended today you'll get a link with a password that'll allow you to do that they'll be good for seven days after that um it'll be at least two weeks before they get everything edited and up on youtube but the plan is for the free sessions they're going to edit them and get a link up on youtube for you um cool thanks for coming appreciate it have a great evening night morning whatever it is for you uh really enjoyed today oh real quick if you have any more questions i'm happy to stick around and ask questions um but again want to be respectful of your time so thank you very much ed has the questions about dark mode and i don't know if i know the answer to your question i know that they just like if you go on the ag grid website they don't provide a dark mode for material um and i don't know i don't have an answer as to why that is i don't know if material i don't know if it supports it in a different way because i don't think they're using i think they followed the material spec but i don't think it's like they're using angular material or material you know there's a bunch of there's a material for views i don't think they're using any of those libraries i think they kind of wrote the theme based on the google material language spec so i don't know why they don't have a dark and maybe that's something that they'll come out with in a future release so all right cool any other questions if you guys want to um talk to brian feel free to raise your hand you can ask him questions and talk to him directly seems like we're winded down [Music] good question alex um actually i'm on a podcast called the angular show which is also part of kind of ng conf and we actually did a show i think it was about two or three months ago it's hard to keep track of time these days but i think it was two or three months ago and we talked a little bit about the gde process um and i think we each kind of shared a little bit about our our process into that but um in general you know i have uh enjoyed being a part of the program it's a great great group of people from really all around the world i think there's about 150 of us or so or 100 i'm not sure and it's just wonderful to be able to engage with people ask questions we do a monthly sync up with the google team and the angular team at google uh mostly the devrel team uh you know so folks like steven fluin and such uh and get some inside look into things it's an opportunity also for us to provide feedback you know it's really important because i think to some extent if you work on a framework you don't actually use the framework a lot you're actually you're more of a firm framework developer rather than a framework user um so like angular doesn't use a framework i mean the only it only has like three dependencies right like typescript zones tslib and rxjs so four i guess um and so it's a really good opportunity for them to get feedback from the community of course they've been doing that through things like the road map rfcs certainly github issues uh conferences but it's another way for us to kind of engage with them and so they got to see what's going on in our world so it's been a pleasant journey and um uh ed wants a pdf from this morning yeah uh it's been a pleasant journey and i've really enjoyed being part of the group and if you're interested in learning more about kind of what the gde program is and maybe how you become a gde i would point you to the angular show so if you go to ng.show we talked about gdes okay maybe it was more than a month ago i'm sorry okay it was that was june it's not that right that's a couple months ago there's an episode here alex um i don't know can i just throw a link in the here you go and you can subscribe to the podcast that would actually help us honestly in terms of just knowing kind of the impact we're having on the community and so we talk about getting into the program why we got and why we joined how we've benefited uh from it and through our careers and kind of all of that and so it's a fun listen so you can check that out ed wants the pdfs from this morning let me do that for you and let me grab that file open getting started oops come on export pdf okay let's give it a minute it's uploading getting started with h grid get link copy all right there you go i'm glad i'm glad you enjoyed ed we uh you know it's funny we do this podcast so i mean we spend uh at least two hours a week doing the podcast and then i also kind of help with some of the logistics around it uh and and such so i probably spend two to three hours a week of my you know personal time if you will kind of doing the podcast and so we actually kind of wanted to make it a little more than just like a straight tech like and and there's nothing wrong with a straight tech podcast where it's just you know uh rate just real you know deep dive and attack or something i mean i love those things too um but we wanted to have some fun and so it's really fun jennifer frosty and myself we just get a hangout we get to learn something we get a you know maybe teach something we get to know people in the community we try to make it representative of the community in terms of diversity and inclusivity and we try to have fun and so we do it's a good mix of i like it it's a good mix of on topic and wildly off topic because we do some stuff and we'll just be like we'll see kind of what happens hopefully hopefully that went well and uh we've got some positive feedback i think the last episode is a pretty uh there's a we've done a couple episodes where we just talk about i think the last episode that we just released is the meta episode where we just talked about why we do it right so why the angular show um but we've talked about a bunch of we did a beautiful i thought a really great job of a six part series on state management we've got a four part series coming out on the rxjs operators so we're going to look at creation operators transformation operators um geez i can't remember the other two creation transformation either way we're into a four-part dive into rxjs operators we're going to do another series on forms talk about template forms reactive forms um and kind of and ngx formally and just kind of get some people together and talk about forms because we're probably all doing it and so we've been trying to be a little diligent to some extent about doing some of these kind of series which hopefully have been well received any other questions otherwise i'm going to sign off and jason is already overstayed you know what i enjoy this jason it's it's been awesome i've really enjoyed this brian and i the angular show is so much fun to listen to you guys are fun so is it i hope so sometimes i help with the show notes like the notes that go out like in the emails and i won't i'll forget to write them up immediately and i'll have to like go back and listen to the show myself and a couple of times like i was so i'm listening to the show and i'm literally just like giggling and my wife is like what are you doing i'm like i'm listening to myself i mean i think i'm funny to some extent but frosty and jennifer and the three of us we have a great time no you got and you can tell that you guys have a great time and it's just something good to have on in the background you know when you're dealing with meetings or whatever don't tell people that you should yeah you should pay attention at meetings maybe ben says operators operators operators so it's like bombers developers chant nice yeah we uh it's hard sometimes to do a podcast on without showing so um you know we don't do we don't show any code right it's not a youtube channel or something and so it can be difficult sometimes when we get into some of these tech stuff but we're gonna do we already had jan nicholas on and we talked about the creation operators and then we've got um um jen forget her last name uh her handle is like nerdsome uh we've got her and zach derose came on recently and we did the [Music] transformation operators i think we're going to do the filter operators and then the join and multicasting operators something like that i don't know maybe we'll go to five we'll see how see how it goes so operator mono nice all right good any other questions otherwise i'm going to sign off probably go drink some tea i don't usually talk this much uh if you i'll throw in a latch last pitch if you're interested in joining me another day this week it's a paid workshop but if you go on ngconf website i'm doing an advanced rxjs workshop speaking of arcsjs um so not sure where it is so here and so i'm going to take you through subjects we'll talk about observable observer we'll look at all the subjects async subject replay subject subject behavior subject websocket subject if you've never used that we'll talk about the multi-casting operators we'll do a deep dive into error handling things like retry when retry throw throw when catch error of course the error notification will look at building a custom operator so kind of what we did today i guess maybe if you will for building custom components but we'll build our own custom operators and then we'll take a look at testing so take a look at testing observables we'll learn about marble testing uh hot versus cold we'll wire that all up with the test scheduler and expect observable and then we'll kind of circle back around to some of our custom operators and then we'll and this is where marble testing really shines it really probably shouldn't be used almost at all for testing your components that use rxjs in my opinion but we'll use it for testing those custom operators that we built so that way we can get some tests around those so it should be a fun time so if you're interested in joining me that's on wednesday so you can come up here and purchase a ticket i think it's 4.99 for a full day of training it is going to be a lot of good content so if you you want to take your rxjs to the next level uh join me and and we're going to do it that sounds [Music] awesome you
Info
Channel: ng-conf
Views: 4,511
Rating: undefined out of 5
Keywords: angular, angularjs, javascript, ngconf, ng-conf, programming, angular conference, ng conference, angular javascript, angular tutorial, Javascript Tutorial, Programming Tutorial, Computer Programming, Google Angular, Google Programming
Id: H9EccfoXVd8
Channel Id: undefined
Length: 151min 58sec (9118 seconds)
Published: Mon Jan 25 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.