So getting projects from A to B is now our goal to be precise when users create a new project when they
enter all data.
We want to create a new project object in the end which we DNA output in our project list class as part
of the unordered list which is rendered there.
That's the idea.
No of course a trivial way of implementing this could be to simply go to the place where the user input
is entered and then here use stock human get element by I.D. to reach out for Dad unordered list.
We rendered as part of our project list class which has this idea here.
So active dash projects list or finished dash projects list and then simply reach out to that and add
a new item to it.
But that's not really Dee's idea of how I want to build this application.
I want to build it in an object oriented way where we have our different classes that work to gather
in a in a reactive way where we create a new class and then something happens in the DOM where we call
a method of a class and then this class does something.
That's how I want these things to work.
Now of course we could add a method to the project list class.
Let's say I add project method.
That method should then be called when a project should be added and rendered.
And we would have to find some way of calling it from inside the project input to do that.
We could make sure that we actually pass references to our lists here to the project input constructor
so that from inside the project input class we can work with these concrete instances and call the methods
on these instances because dad is what we would have to do that would be a while.
Way definitely an approach you could take but I want to take an even more abstract approach even more
interesting approach in my opinion I will build a class which manages the state of our application so
to say a class which manages our projects or whichever state we might need to manage in the application
which also allows us to then set up listeners in the different parts of the app that are interested.
This is a pattern that might sound familiar to you if you work with frameworks like angular or library
is like react and read X that you have a global state management object and you just listen to change
as that is what I want to implement here.
Of course it's just one way of doing this but I think it's a quite interesting way which is why I want
to show it.
So at the top of the app yes fall I'll add a project state management class and I will simply name it
project state.
Sounds like a sensible name to me now.
The idea here is that in this class we have a property or a field a private field projects which holds
an array of projects.
Now we all need to define how a project should look like.
We'll do that in the next step.
For now I'll just say it's an array of anything.
Which of course is not perfect.
Not final but I want to focus on that state management solution for now.
So we have this list of projects here now my goal is that I want to add an item to that list whenever
we well click that at Project button here to make that work inside of the project state class I'll add
a add project method a public one and there I expect to get the title which should be a string the description
which should be a string and also the number of people working on the project which should be a number.
Then in here we can create a new project with the object literal notation for now where we should have
some I.D. for every project so that we can uniquely identify it and I'll generate an idea here by using
moth random to string now a random number is not really a unique idea.
You can generate the same number more than once but it's very unlikely and for our demo purposes here
it will do.
Now besides that every project should have a title and there will stored that title argument we're getting.
Same for description where I will store description and my people where I will store the number of people
this for now is the project I want to store.
So once we created it here we can reach out to the project's array and project state which is private
but from inside the class which this method is we can access it of course and they want to add this
new project and for that we can simply push our new project to it.
Now with that we are able to add a project but we still of course have a couple of unclear questions.
How do we call at Project from inside our class down data or what regather the user input from inside
the submit handler.
How do we call at project and how do we pass that updated list of projects when average changes to the
project list class.
These are the two issues we of course face at the moment.
Well one thing I will do here is I will create an instance of project state here a global instance which
we could use from the entire file and I'll do it right after we create that class.
So here I have my project state constant where I instantiate projects state like this.
This way does is a global concept that can be used anywhere in the file.
So talking to that class is now super simple.
You just have to use this global constant here we can even use a feature we all learn about the private
constructor to guarantee that this is a singleton class we can create a private constructor here and
then we have a never private property here instance which is of type project state self the same type
as classes off and we then add get instance method here a static method actually where we check if this
stored instance is a thing.
And for Dad this actually all that has to be a static instance a static property I mean if this is a
thing if it is we return this stored instance so we'd return our single instance we got.
Otherwise we create a new one.
So either wise this dot instance will be equal to new project state and then we return this stored instance
now is that we can call get instance down there like this project state get instance and we're guaranteed
to always work with the exact same object and we'll always only have one object of the type in the entire
application which is the idea here because I only want to have one state management object for our project
and Dad is this project state with this Singleton constructor now.
So now we have our project state constant.
Let's go down to the project input class day offer where we gathered a user input here we can now call
Project state app project and forward to title the description and the people we get back from.
Gather user input in yet.
So now this project should get created.
Now we just need to push that information that we have a new project to our project list class because
that's the class which is responsible for outputting something to the screen and for data want to set
up a subscription pattern in the end we're inside of our project state we manage a list of listeners.
So a list of functions in the end which should be called whenever something changes.
So for data all add up no private property here.
Listeners and listeners will be an empty array.
And for now again just an array of anything we will specified as in greater detail later now.
I also want to have a method here add listener where I get a listener function.
So this should be a function in the end here.
And I will then add this to my listener.
So we push the listener function here too well the listeners array.
Now what's the idea of having that listeners are right.
It's an array of functions of function references right.
The idea is that whenever something changes like here when we add a new project we call all listener
functions.
So we loop through all listeners of this listener.
So through all listener functions and then since these are function references we can execute this as
a function and queue that function we pass the thing that's relevant for it.
Based on the state we're managing which in this case of this clause of course is our projects list.
This is the state this class is responsible for so here I forward this project and I will call slice
on it to only return a copy off that array and not the original array so that it can't be added it from
the place where the listener functions coming from because I raise and objects are reference values
in javascript.
So if you would pass the original array we could added it from outside and also on the same hand if
we push something to it from inside this class it would already change everywhere else in the app.
But these places would not really notice that it changed so we could introduce strange bugs if we pass
around the original reference which is why I pass around the brand new copy a brand new Array here.
So now every listener function is getting executed and gets our copy our brand new copy of projects.
Now we just need to go to the places where we want to be informed about changes.
In our case the project list class here and set up such a listener so here in the constructor of the
project list class before we attach and render the content.
I will reach out to project state and call at listener here to basically register a listener function
here.
Now a listener as I said is a function so we have to pass a function to add listener because the listeners
were managing here in the project state.
That's just a list of functions which we will eventually call when something changes right so we need
to pass a function to my ADD listener function here.
Here in passing an anonymous arrow function and that function will get a list of projects when it is
called from inside project state.
So we get a list of projects we know that inside of this function body we can then use this list of
projects.
And here I will add a brand new field to the project list assigned projects maybe which is of type any
array.
So anything in an array an array of any values will of course also specify design greater detail later.
And then here we can say this assigned project is equal to projects so to the projects we're getting
now here to get rid of that implicit any type error.
I have to be clear that this will actually be an array of anything here.
So now I'm adding the projects which I get because something changed in my state here to my assigned
projects or I'm not adding it I'm overriding the assigned projects with the new projects and then my
ideas to render all these projects for that we can add a new method render projects for example which
I want to call from in here.
This render projects just like this.
It ends out of render projects.
I'll reach out to this list here.
Right.
We assign that I.D. when we render the content which we do here.
It looks like we do this after and our project is called but keep in mind that's instead of a function
which will only eventually be called once new projects are added so actually render the content will
run first and therefore in rendered projects we can rely on this idea being assigned to an unordered
list.
So here we can grab this and get our list element by using document get element by I.D. And then I just
pass in this idea identifier using the type of this concrete project list class and then also using
while the rest of this idea we generated and to that list or in that list I want to render all the projects
we have so I will go through all the project items of this assigned projects here and then for every
item I want to add something to the list and we'll refined this later.
For the moment I will just call append child here on my list element by the way here we should add an
exclamation mark to make it clear that this will not be null.
We can also cost us to an h t male U L list element to add to an unordered list element because dad
is what it will be and then we can append a child here and that should be a brand new list item.
So here we can create our list item with document create element l I add on that list item here I just
will set the text content equal to project item dot title every project item will be a project as we
created up there in the project state so it will be such an object and therefore it will have a title
with that if we go down there we have our list item which now is added here and with that we're almost
there remaining fixes here.
I set up that field but in the constructor I then never reference it only here in my listener function.
But as mentioned this does not run immediately in the constructor.
So what I'll do here is I will set this assigned projects equal to an empty array here initially so
that we're all happy and this is initialized.
Now if we save this it should compile without errors.
And now if we add something here.
Dust is work we indeed teams show up in our lists in both lists at the moment because we have no filtering
logic and so on.
And that is something we can fix later.
But it does work and that's the important thing.
Now you see we also have a box here.
However if I add a second element we duplicate the last element and add the new element.
So that's something we'll have to fix.
And these are all things we will tackle.
But now at least we're able to output something with that.
Let's dive into all the improvements like being clearer about the types we're using a widening that
duplicate output and many other things as well.