 Okay, so I'm going to talk now about the data store and going to share my screen. And we are going to start with. What is the data store so the data store is. It's basically a key value store for storing JSON objects in the DHS to database. This is really handy because it allows you to and to not only store things that fit very well into the DHS to data models things like data sets indicators, data values, visualizations, things like that. That have a pretty rigid structure. And so for a lot of things that make sense to store them in the DHS to data model particularly Martin is raising his hand. Okay, yeah, the data store is a key value stores that that fits into the DHS to database. And if possible, it should, you should always look at using the DHS to data model to model the things that you want to save from from your application. Because that makes it much easier to for for other apps and the core apps to interact with that data as well. And but there are some cases where what is possible out of the box by are provided out of the box by the DHS to data database and the data model isn't a good fit for the application that you're building. So, in order to address that we have two data stores actually in DHS to one is called the user data store, and that is specific to the DHS to user who is currently logged in. And so anything in the user data store can only be seen by that one user. And whereas in the data store, it's a global key value store, which means that when you put an object into the data store, the global data store, it can it's visible and editable by everyone by default. So there actually is a fair amount that you want to consider that we'll talk about tomorrow in terms of how to set the sharing settings on objects in the data store to make sure that they are restricted to the people who should actually have access to them. And you have to be a little bit careful when you're putting things into the data store because you might be you don't want to store everything in a very public and editable way. So what kinds of things might you store in the data store or the user data store and for web applications, the two major use cases that we'll talk about today that that I've seen people using are for settings for their application and for saved objects. We've actually built a library that is a wrapper around the data store API and provide support for these two use cases. And what what are those two use cases mean. First of all, settings is typically when you first access an application, maybe you need to configure it to talk to or to reference a particular indicator by ID that you don't know what the ID of that indicator is when you're building your application. So you need to configure it at runtime. But you don't want it to configure it every time a user goes to your application. So you want to save that ID of that indicator into somewhere that will it will remain and can be referenced later. And that's what the data store is for. That's what we call a setting. So if you have a setting for the ID of an indicator, you save that into the data store. Let's say initially we're saving that just into the user data store. And whenever that user comes back to the application, it can reference the user data source see that there was already a configuration that happened that they chose a particular indicator ID, and then you can show that right off the bat without needing to have them go through a configuration step again. However, if another user comes to use your application, they will see the configuration interface, because the day the configuration stored in the user data store specific to the other user. Instead it was stored in the in the global data store and shared between all users of DHS to then it would one person could configure it and everyone else would be able to just access that information and see the see the results or see the configured application. So that's what a setting is. There's a lot of use cases for settings and typically something like referencing metadata in DHS to is a good one, but there are a lot of other ones which might be turning on and off features of your applications for for specific users or specific user groups, and there's a lot of other saving information that needs to be referenced later that isn't necessarily configuration but just is a piece of data that you need to kind of persist longer than the session of your user on your application, the the other use case that we'll talk about for. Yeah, so we can only see the same slide data store and user data store I don't know if you're sharing a different window. No, that's all I'm sharing. Okay. Yeah, so the, the, yeah, the, the other use case that we often see is called saved objects. And what a saved object is, is basically it's like a visualization in the analytics apps in DHS to so when you go to the data visualizer application. You can click file open, and you see a list of all of the visualizations that you have already created, which have been configured in a particular way. And there's, it could be one of those it could be 10 it could be 100. You don't know and they might also be some visualizations that are shared with you by another user. And so that's the idea of shared objects are saved objects in the data store in custom applications as well as to have a sort of a lightweight version of that visualization engine where you can save the configuration of a visualization or the configuration of something that the user creates, and then you can reference the list of all those things that the user has already created, as well as use them to generate a visualization for example. So we're going to get into how to how to use the data store application service in order to address both of these and the the second to last line here on this slide talks about that service which is available at DHS to slash app service and it's packaged on npm, and we'll go through that in the presentation today as well as in the in the exercise. And it basically can be used to interact with the data store in the user data store. So visit the data store manager application, which lets you visualize all of the objects and edit all the objects that are in the global data store. That does not give you access to the user data store at this point. And but that can be useful for debugging and things as well. But you can also visit the use the API to dump all of the data from the data store and the user data store. And then the app service data store it's a, it's not an official service yet. So we've developed it there are a number of applications that are using it but we still want to make some improvements before we officially make it a part of the app runtime. And that should be happening fairly soon. And but for now I'll go through what exists today and how how it works how you can use it in your applications to add it to your app. So we're going to learn add up at DHS to you slash app service data store. And we'll get into more of that in a minute. And first thing you need to do when you're using this wrapper or this app service is to wrap your entire application in a data store provider data store provider is exported by app service data store. You can specify a namespace for the that your application will use in the data store. And that then you can just quickly and easily set settings and add and remove and update and view saved objects from that namespace in the data store. I put a little note here down at the bottom this is be sure to specify data store namespace in d2.config.js to reserve this namespace for your application. If you're not using the platform, you can specify that in the manifest file in the d2.config.js name space. And but there's there's more about that in the documentation as well. It's important to keep this name as unique as possible, because if you reserve it in the whether or not you reserve it but if you reserve it in the manifest file or in the d2.config.js file, then no other application will be able to be installed with that same namespace. This is nice for security meaning that only users that have access to your app will be able to see that namespace, and no other apps can kind of co work co-opt it or override it. If you use a very simple name like app, then it's very easy to have conflicts with other applications. So it's recommended to use something that includes the name of your application and is complex enough that it's going to be globally unique. Once you have your provider setup in the app service or the data store provider setup in your application, you can use these four hooks anywhere in your app in order to access the settings for your particular application. So the first hook here is called use all settings. And basically that returns a list of all the settings or a map sorry of all the settings that have been configured for your application. You can optionally in this data store provider you can pass defaults if you want to have a default value for that setting. The all user settings as we say here and returns the settings that exist in the user data store. So these are settings that are specific to this particular user. Whereas if you set the global true flag in the object that's passed out to use all settings, then it will return the settings from the data store, rather than the user data store, which means that it is shared with all other users of DHS to you can also get an individual setting from either the user setting the user data store or the data store using the use setting hook, and you just pass the ID of the setting that you want to request, and that will return that value as a user setting. These also has a, a set function that's returned as part of an object that's the second return value here. And so use setting for instance has not only the value of the user setting which will then cause a re render of your component whenever that setting is anywhere in your application. And, but it also has a set function, which allows you to basically set the value of that particular setting, or in the use all settings case, this set function takes a an ID, as well as a value, and we'll set the value of a particular setting here. I should go back here. Yeah. So that's, that's settings, and we talked about also saved objects. There are two hooks also for accessing saved objects, one is used saved object list, which will return the list of all saved objects in the namespace that you specified. And in this case, there is a, we're accessing first the saved objects for this particular user, which might not, which are not shared with any other users. So this could be problematic, or difficult to use in some cases. So if you want to do sharing, you can't use this saved object list you need to use the global true setting in your in your saved object list, which you can then do here, and that will return all of the globally shared objects in there is also the concept of a specific saved objects similar to a specific setting, you can use the use saved object hook and just pass a an ID, and exactly the same as settings, you can pass a global true flag to specify that this should this ID one exists in the global data store rather than the user data store. As I mentioned, we can also use hooks use these hooks to mutate the data that's our that exists in the data store so we have update replace and remove when we specify a use saved object with an ID. We return the value, it will re render the component whenever that value changes anywhere else in the application. It will then also have a function which you can call with a new value to update it and this will merge with the existing value, you can replace which will as it as it sounds replace the existing objects so everything that you pass here to the replace function will be the new object and the old one will be removed, and you can also just remove the object completely. And you can use a do have the same functions in the use saved object list as well. So this has add update replace and remove for update at replace and remove you need to pass an ID for the object that you want to modify. And that's about it for the for the data store I'm going to go quickly through the the code example that are the exercise that will have people going through. And but first I'm going to open up the service data store so this is where you can find the the code and some basic documentation in the in the read me here about this service. And so these are the the hooks that are available. This is the these are the options that are available. You can also see some examples that are basically what I just showed you of how to wrap your application and do store provider. There's a list up here of the the properties that are possible to pass to that data store provider. And then there are some examples of the different ways to use these hooks for the exercise today we have a fairly simple, but maybe a little bit more complicated than the translation one. For example, it's in this data store folder. You can fork a code sandbox by opening this link. And there are four tasks here. So first you need to initialize your data store provider which will be something that you do in the source app.js component. You then will render a list of saved visualization objects and you'll support adding new visualizations into the user data store. And you'll then you'll also support deleting those visualizations and just to kind of demonstrate this. I'm also going to open up. Actually, let me see if I can do this here. I'm going to go ahead and open up this folder locally and run it. So there's there's also a solution that's already available here if you have any trouble or just want to reference this later. And I'm going to show what that looks like just so that we know what what the goal is here. So data store solution. You're going to do your own start. This is a DH2 platform application of course. Here's the application. Loading here. And I need to run the first colleges. Sorry, I think I did a copy on this. And so my node modules is messed up. I'm going to highlight this and reinstall. But in the meantime, when you open this up in the code sandbox, and you'll see that they're here you have your four tasks. Again, in this read me, and you can then look into the source directory. This is where you're going to start first, you need to import the data store provider and wrap the visualization list in a data store provider with the namespace of this one. You can see that in our d2.config.js we have reserved that namespace for this application. And then there are additional tasks. So the first task is in app.js. The second and third tasks are in visualization list with a little bit in remove button as well. Sorry, in add control for task three. And then there's a final fourth task in remove button. And basically we're just adding the use of the data store to this application. And that should be should be good. Let's see if our. Yarn has finished here. I'll take a moment, but it should come up. And I will show you what the end result should look like. Anybody have any questions about the data store presentation that I gave, or any questions at all. Yeah, there's a question in the chat. Yeah, so the question is does this automatically create the namespace if it does not already exist. It does create the namespace when you create the first key within that namespace. So that's how the data store works. It will not create a namespace outright. I'm not sure what's going on here with my. It will not create the namespace when you start. And because there, there's no keys. So there's no name that namespace doesn't exist unless it has keys in the DHS to get a store. But it will create that namespace automatically when you set anything in the settings or saved objects. And as well, if you set a default value for the global or the user settings, it will create that when if it doesn't exist, it will create that on startup. Hopefully that answers your question. So here, here's what we're what we're working on. I just logged into a server through my application on local host, 8080. You'll see that I do have a an alert that I can show by just clicking this and it says they must enter a name for the new visualization. So you can see, check that out. If you're still trying to get familiar comfortable with the alert service. That's in the add add control file. And then we can create a name so my visualization or something like this. Remember this is saved in the data store it's specific to this application so you can the structure of the objects in that data store can do whatever you want. So we're going to go ahead and add that visualization. We can do another one that says this is a test. Visualization test to test three. So now we've created these visualizations if I refresh my page. I still see these visualizations. If I go to debug 234 which is what, which is the server that I'm talking to, and go to API 34 user data store. I can see that I have this namespace that was created. I can then go to that namespace and see that I have a settings and a save objects key, and I can go to the settings key. Let's see that there's nothing there and saved objects. I can see that I have those four visualizations and each one of them has a generated ID, so it will be globally unique. It has a name that we're specifying but this object could have anything else as well so it could have whatever properties you want that you need for your visualizations that you want to save. And you could use them in your application. And for now, though, the end result of this is we can just add visualizations and then we can also remove them. So we can go ahead and remove those from the list. We can now see that if I refresh this there's only one visualization left. You can see also from this that this is saved as a in the data store in the database so it's it's persisted for basically until until those objects are deleted. If now I just quickly log in as a different user. And this user because I haven't actually opened this application and in the user data store there's no there's nothing in this namespace yet. If the namespace doesn't actually exist. And that's because the, the saved objects are saved in the user data store. Yeah, and so that's specific to the user that I was logged into previously, which was the admin user, I can now refresh this and say, and new visualization, another visualization at that. And now I'll see that it has been created here in this for this user as well. But if I log back in at the other user would see the visualizations that that user had created. I'm sure I had a good question which is can you store a nested object so if we go back to the, and my custom names with saved objects we have this, this object. Yes, this can be a deeply nested object. You can't request the subset of that object you have to get the entire object at once in the in the application, but if in our code base here. We can add, for instance, and I think it's going to be an add control. And this is giving away a little bit of the result but we actually call this add with a name, new, new vis type and we say like data is some deeply nested object. That actually work as well so I can save this, and then create a new visualization. You should have to be careful when you're doing this because if you change the format of the object in the data store you need to do the migrations that yourself it's basically you're managing a database. But if I said, refresh this and say, I'm testing at visualization, if I go back here. See that this testing has a deeply nested data structure as well so it's a full JSON representation of an object in this. Thank you.