In this video, we learn to accelerate development by using the integrated VS Code plugin to generate new models in the IDE.
See how models are generated using best practices to improve the developer experience. Explore how model features can be dynamically activated in the tools.
So, quick recap, we manually created a model and registered it with the framework.
We’ve been able to use the KOS Fetch utility to grab data from a backend endpoint and update the model as part of the model’s load lifecycle.
So the next thing is, how do we use this model in other places in the framework?
So we’ve got this nice self-contained model.
Right now it’s preloaded, but let’s say we didn’t want to do that.
Let’s say we wanted to make it part of our dispenser so that it could be composed into the dispenser model so that we can start to show things on the UI, for example.
So the first thing I’m going to do is actually remove the preload so the model’s no longer going to get created automatically.
We can see that here.
If we look in our console and reload, we’re no longer seeing that model getting created.
So how do we bring this back into the framework?
We talked about using the dispenser model here.
So the simplest thing would be, let’s create a new type on here.
This is the interface for the dispenser model, and let’s just create a new system info, which is going to use the system info model interface that’s getting imported here.
You can see things are starting to go red, specifically because I haven’t implemented this property yet.
So if I say system info, which is going to be system info model, for now, let’s do the simplest thing, which is just instantiate it as part of this model.
All right, so in this case, I’ll say, this system info is equal to, and this is where we’re going to start to use the KOS model factories that are available.
We’re going to use a low-level implementation of it.
When we get into the tooling, you’ll start to see how we can really streamline the use.
We use a factory to allow this model to participate in the framework.
It’s going to kick off the lifecycle and just generally make sure it’s registered with the framework properly.
Rather than just using a straight constructor, we want to make sure that everything is flowing through properly.
So for creating and using instances of models, we’re going to use the factory, and the main reason is for caching purposes.
So if we create a model and we use the factory, if it already exists in the cache, it’ll retrieve that version rather than creating a new instance.
So it really helps with resource management as well as just ensuring that everything is loading in the appropriate order and time.
So to do this, we’re going to create a KOS, use a utility called KOS, which is coming out of the core SDK.
And if you recall, we created this one as a singleton.
So if we actually say singleton create, now the singleton takes a property, which is the type.
So we’ll actually say it’s a generic type.
So we’ll say we’ll take the system info model, system info options, and the type is the system info model.
So this is actually a curried function.
So it’s going to return the factory, and then I’m going to instantiate it by passing in any of the data.
So you can think of it in two parts.
There’s the first create, which returns a factory for one of these types of models.
And then the second part is allowing me to pass in whatever data I want as part of it when it’s constructed.
So in this case, I don’t need to pass anything in, but it’ll allow me to create it.
So this actually introduces an interesting problem, which is I have this model, and it’s got its own life cycle.
I want to make sure that it’s available before I start using it.
So one of the things that I can do is decorate this type as a child.
So I can say, at KOS child, and that will register with the system that this thing is actually a child model to this one.
So it will now participate in lockstep with the life cycle of this model.
So it’ll ensure that this particular model will be ready before this model can declare it’s ready.
So the system info is now going to be tied to the life cycle of the overall system.
So it means that the system info, when it’s going to go to its asynchronous calls, those things will be guaranteed to be done before we get back and say that this thing is ready.
So if we were to go into here, we could actually validate that and say, I want to use the logger, warn this system info dot app ID, let’s say, move this stuff over.
So what you’re seeing is it’s being created.
We see it initially created with the app ID, and then we’re seeing the app ID as it’s coming in from the model after it’s already loaded.
So you’re actually seeing how these things are connected.
You’re also seeing some of the way that the life cycles are tied together.
So now in our dispenser model, we’ve instantiated a new model using the factory.
There are other ways and better ways to do that, depending on the types of relationships you want to model.
And then you can see that as part of the life cycle in the ready phase, I’m able to see the values with guarantees that it’s going to be returned.
The way that these dependencies work with children is, it’s not going to be ready until all of its children run through its life cycle entirely.
That means that by the time I get to the ready function here, all the children are already available to me.
So why can I get access to the data at that point?
In another section, we’ll take a look at dependencies rather than parent-child relationships, but it’s important to show it at this point.
But the important thing here is I’ve now got a relationship that exists and I can peer into the data on this model.
So I have now the ability to compose my dispenser model with a number of these smaller models, each which have their own distinct life cycles and can be managed individually.
That’s really powerful and something that we’ll be able to use as we go further into our dispensers.
What we wanted to do though was say, well, how can we use this information?
I can see it’s ready here, but I want to be able to use it in the UI somewhere.
So let’s go now and add some data to the UI for the first time.
So I can go into my app and there is a component dispenser view.
We’re going to put this at the top level for now.
We’ll look at creating components in a little bit.
But for now, let’s just add a new property here, which is going to be, I believe it was the app ID or the app class rather, in this case, we’ll go off the dispenser.
We’ll get the system info because it’s part of the contract.
And we will say, we’ll get the app class off of it.
And you can see live reload happened and it’s populated with the values.
I can reload and it’ll pop up same thing.
So it’s going through the life cycle and it’s just available to me to use.
There’s nothing I need to say in the framework to register it or anything.
It becomes available for me.
This is really important because as things change, it’ll automatically refresh and we’ll get into the reactivity side and the observability of these models in a moment.
But what’s really important is that I’ve now got access to the data and it can be hooked into the UI relatively easily, which is one of the reasons why we wanted to create the contract the way we did.
If we go back to our model, so the fact by virtue of us creating this contract, the teams can actually go off and the various pillars can go build the implementation on one side of the model and go build the integration in the UI on the other side using the interfaces.
And it means that you’re not stuck at any one particular point.
You can dig the tunnel at both sides, so to speak.
But more importantly, as we have an established contract that says the model lives between the two pillars and allows for an integration to occur.
Bye!