- 00:00:02 hi everyone
- 00:00:03 in this video i want to dive into how
- 00:00:05 you can take an angular app or
- 00:00:06 build an angular app and connect a node
- 00:00:09 express and mongodb app
- 00:00:11 to it now this is an excerpt from my
- 00:00:14 full um course
- 00:00:15 link with a great discount in the video
- 00:00:17 description it's a big excerpt though
- 00:00:19 you'll learn all the theory about how
- 00:00:20 these two ends work together
- 00:00:22 node express mongo and angular on the
- 00:00:24 other hand and we'll also start building
- 00:00:26 this
- 00:00:27 would obviously be awesome to welcome
- 00:00:28 you in this course but this video
- 00:00:30 already
- 00:00:30 should get you started with the mean
- 00:00:32 stack an awesome technology for building
- 00:00:34 full stack apps with angular on the
- 00:00:36 front end
- 00:00:47 welcome to this course it's really great
- 00:00:49 to have you on board
- 00:00:50 as a student in this course we'll dive
- 00:00:53 deeply into the mean stack
- 00:00:55 that stands for mongodb express.js
- 00:00:59 angular and node and it means that we're
- 00:01:02 going to build an
- 00:01:02 angular application which is a
- 00:01:04 client-side framework for building
- 00:01:06 beautiful uis
- 00:01:07 and also at a backend built with node in
- 00:01:10 express and using mongodb as a database
- 00:01:14 and therefore you'll see the full
- 00:01:16 picture of creating a full stack
- 00:01:18 angular application so that's really
- 00:01:20 going to be amazing and in this course
- 00:01:22 we'll cover a lot of cool features
- 00:01:26 all the basics of course but also things
- 00:01:28 like image upload
- 00:01:29 pagination authentication authorization
- 00:01:33 so how to control that only users who
- 00:01:35 created
- 00:01:36 some content can edit or delete that
- 00:01:38 content
- 00:01:39 how to deploy that on one server or on
- 00:01:43 multiple servers
- 00:01:44 and so much more now i'm really excited
- 00:01:46 to dive into all of that
- 00:01:48 together with you the question now is
- 00:01:50 who am i
- 00:01:51 my name is max i'm maximilian
- 00:01:53 schwarzmuller i'm a freelance web
- 00:01:54 developer
- 00:01:55 and udemy instructor i got multiple five
- 00:01:57 star rated courses here on udemy
- 00:01:59 like my angular the complete guide
- 00:02:01 course which is a great starting point
- 00:02:03 before you dive into that course
- 00:02:05 and i worked with angular and all these
- 00:02:08 technologies shown in this course
- 00:02:10 for a very long time i'm so happy to
- 00:02:13 share that knowledge with you
- 00:02:15 and i actually created this course two
- 00:02:17 years ago already
- 00:02:18 i completely revamped it now in 2018 so
- 00:02:22 that you're learning the latest
- 00:02:24 and greatest of all these technologies
- 00:02:27 and with that let's get started and
- 00:02:29 let's dive into that
- 00:02:30 let's start by understanding what the
- 00:02:32 mean stack actually means and comprises
- 00:02:35 and let's then add all these cool
- 00:02:36 features i was mentioning
- 00:02:38 step by step
- 00:02:48 so what does mean stand for what are the
- 00:02:51 different components we'll learn about
- 00:02:53 in this course
- 00:02:54 mean comprises a set of four
- 00:02:56 technologies
- 00:02:57 and this is what it stands for the m
- 00:03:01 stands for mongodb and it's the database
- 00:03:04 we'll use in this course
- 00:03:06 so the part where we will be able to
- 00:03:08 persist the data
- 00:03:09 the users of our application generate
- 00:03:12 like the user data itself
- 00:03:14 but also like posts or messages they
- 00:03:16 send things like that
- 00:03:18 the e stands for express and express js
- 00:03:22 is hard to understand without the n
- 00:03:24 so let's quickly fast forward we also
- 00:03:27 get the a
- 00:03:28 and the a stands for angular now i'll
- 00:03:30 come back to that n
- 00:03:32 which is related to the e but angular is
- 00:03:35 our
- 00:03:35 client-side technology it is a
- 00:03:38 javascript framework in the end which we
- 00:03:40 will use
- 00:03:41 to render a nice dynamic ui user
- 00:03:44 interface
- 00:03:44 to our users it runs entirely in the
- 00:03:47 browser
- 00:03:48 not on the server at all and therefore
- 00:03:50 it really has just one
- 00:03:52 job presenting a nice and pleasant
- 00:03:55 interactive and reactive user interface
- 00:03:58 now what's the end then well you
- 00:04:01 probably already saw that something is
- 00:04:02 missing
- 00:04:03 we got a database and we get something
- 00:04:05 running in the browser
- 00:04:07 but we certainly also need to run some
- 00:04:09 logic on the server
- 00:04:10 for example authenticating users this is
- 00:04:13 not something we can do in the browser
- 00:04:15 because a browser code can easily be
- 00:04:18 hacked or changed and b
- 00:04:21 it's way too complex it would take up
- 00:04:24 quite a significant amount of resources
- 00:04:26 and slow down our front end
- 00:04:28 our user interface n stands for
- 00:04:31 nodejs and it's the javascript
- 00:04:34 runtime the server side language
- 00:04:37 we'll use in this course for our
- 00:04:40 server-side code so for our core
- 00:04:42 business logic that runs on the server
- 00:04:44 and now the e
- 00:04:45 also is related to it because whilst
- 00:04:47 node.js
- 00:04:48 is the language we'll use on the server
- 00:04:51 express is a framework for
- 00:04:53 node.js that makes working with it
- 00:04:55 easier you wouldn't need express shares
- 00:04:57 per se
- 00:04:58 but it makes working with it much easier
- 00:05:00 just as angular is a framework for
- 00:05:03 javascript in the browser
- 00:05:04 you don't need it but it makes things
- 00:05:06 easier but let's take a more detailed
- 00:05:08 look at all these things
- 00:05:09 now i want to look at angular first as i
- 00:05:12 already said angular runs on the client
- 00:05:14 side
- 00:05:14 in the browser it's a framework
- 00:05:18 building up on javascript or using
- 00:05:20 javascript
- 00:05:21 and it's used to create so-called single
- 00:05:24 page applications
- 00:05:26 this essentially means that it handles
- 00:05:27 the entire front-end
- 00:05:29 logic so everything your user is going
- 00:05:31 to see angular is responsible for it but
- 00:05:33 i'll come back to it
- 00:05:34 in a few seconds angular's job is to
- 00:05:37 render
- 00:05:38 the user interface with dynamic data and
- 00:05:40 that dynamic data part is important of
- 00:05:42 course
- 00:05:43 its job is not just to render some
- 00:05:45 static html
- 00:05:47 and some css we wouldn't need javascript
- 00:05:49 for that
- 00:05:50 its job is to update the ui whenever we
- 00:05:53 have new information let's say when you
- 00:05:55 create a new post
- 00:05:56 we want to immediately update the ui to
- 00:05:58 show that new post there
- 00:06:00 it also is responsible for handling user
- 00:06:03 input so
- 00:06:04 validating that user input and also
- 00:06:06 sending it to the server
- 00:06:07 because that's the third part it does it
- 00:06:09 communicates with our backend so with
- 00:06:11 that node express
- 00:06:12 mongo combination that seems to be
- 00:06:14 responsible for that
- 00:06:16 angular provides a mobile app-like user
- 00:06:18 experience because since we handle
- 00:06:20 everything
- 00:06:21 in the browser through javascript we
- 00:06:23 never need to reload the page
- 00:06:26 we just change parts of the page with
- 00:06:28 javascript through angular
- 00:06:30 and therefore everything happens
- 00:06:31 instantly in a very reactive way
- 00:06:34 and that is the feeling we know from
- 00:06:36 mobile apps now that is still only the
- 00:06:38 front end though
- 00:06:39 as i said node.js is the language we're
- 00:06:42 going to use for the backend
- 00:06:43 so on the server side which we also
- 00:06:45 build in this course
- 00:06:47 node.js is a server-side library
- 00:06:49 javascript runtime
- 00:06:50 and you know that javascript can run in
- 00:06:53 the browser while node.js simply takes
- 00:06:55 it
- 00:06:55 add some things that are useful on the
- 00:06:58 server like working with files working
- 00:06:59 with http requests
- 00:07:01 and now we can use javascript on the
- 00:07:03 server too pretty amazing
- 00:07:05 node.js listens to incoming requests and
- 00:07:07 is able to send back responses
- 00:07:09 for example our angular app could send a
- 00:07:12 request
- 00:07:12 to fetch a list of all the posts and
- 00:07:15 node could handle a request
- 00:07:16 do something reach out to the database
- 00:07:18 and send back a response with all these
- 00:07:20 posts
- 00:07:22 node.js executes server side logic in
- 00:07:24 general
- 00:07:25 so authentication anything we don't want
- 00:07:27 to run on the browser for
- 00:07:29 security or performance reasons and
- 00:07:31 node.js is able to interact with
- 00:07:33 databases and files
- 00:07:35 angular can't do this it doesn't have
- 00:07:37 access to any file system
- 00:07:38 and especially not to a file system on
- 00:07:40 some remote machine on a server
- 00:07:42 and whilst theoretically you could
- 00:07:44 connect to a database from angular
- 00:07:47 since all your client-side javascript
- 00:07:49 code is visible to users
- 00:07:50 you can have a look at it in your
- 00:07:52 developer tools of your browser
- 00:07:54 it would be very insecure to connect
- 00:07:56 your database there because you would
- 00:07:58 expose
- 00:07:59 all your credentials and everything you
- 00:08:00 don't want to do that
- 00:08:02 therefore node.js is an alternative to
- 00:08:05 php if you know that or ruby on rails
- 00:08:07 asp.net things like that and it's rarely
- 00:08:10 used standalone
- 00:08:11 just like these languages you typically
- 00:08:13 use a framework along with it
- 00:08:15 and that framework you typically use is
- 00:08:17 express
- 00:08:18 express is a node.js framework so it
- 00:08:21 still uses node.js the same language
- 00:08:24 but it adds a lot of utility features so
- 00:08:26 it offers additional functionalities or
- 00:08:29 in general it makes things easier
- 00:08:31 express.js is middleware based
- 00:08:34 and we'll see what this means once we
- 00:08:36 dive into the code
- 00:08:37 it basically funnels incoming requests
- 00:08:40 through
- 00:08:41 a chain of middlewares of steps where we
- 00:08:44 can do something with the request
- 00:08:46 read some data from it manipulate it
- 00:08:49 check if the user is authenticated or
- 00:08:51 basically send back a response
- 00:08:52 immediately this chain allows us to
- 00:08:55 write very structured code and you will
- 00:08:57 learn everything about it
- 00:08:58 in this course of course and last but
- 00:09:00 not least
- 00:09:01 it includes routing which means we could
- 00:09:04 render
- 00:09:04 views so html page pages with it we're
- 00:09:07 not going to do this in this course
- 00:09:09 though because angular should handle our
- 00:09:10 entire frontend and again this is also
- 00:09:12 something we'll see
- 00:09:14 but more importantly we can handle
- 00:09:16 different requests to different
- 00:09:18 endpoints which will be important for
- 00:09:21 connecting
- 00:09:21 angular to the back end because if we
- 00:09:23 want to fetch a list of posts we want to
- 00:09:25 send some requests to
- 00:09:27 slash posts so our domain slash posts
- 00:09:31 if we want to create a new post we want
- 00:09:33 to send a different request
- 00:09:34 to our domain slash post for example and
- 00:09:38 express.js allows us to implement this
- 00:09:40 routing logic so that different requests
- 00:09:43 to different urls
- 00:09:44 are handled correctly again this will
- 00:09:46 all be implemented step by step
- 00:09:48 throughout the course
- 00:09:49 so to sum it up express.js simplifies
- 00:09:52 the usage of nodejs it is a tool we
- 00:09:54 definitely want to use
- 00:09:55 if you have a php background for example
- 00:09:58 you could compare it to laravel for php
- 00:10:00 it makes things easier there's one thing
- 00:10:03 missing
- 00:10:03 and that is mongodb of course mongodb
- 00:10:06 as i already said is a database it's a
- 00:10:09 nosql database to be precise
- 00:10:12 and it stores so-called documents in
- 00:10:14 so-called collections
- 00:10:16 now chances are you might have heard
- 00:10:18 about sql databases like mysql
- 00:10:21 microsoft sql where you have records
- 00:10:24 rows which you store in tables now
- 00:10:28 nosql has a different logic than sql
- 00:10:30 databases
- 00:10:31 but in general it's still a database so
- 00:10:33 you store your application data
- 00:10:36 on a server so that it persists across
- 00:10:39 page reloads across the user leaving
- 00:10:41 your page
- 00:10:42 things like that so any data that is not
- 00:10:46 just temporary data definitely has to be
- 00:10:48 stored in such a database
- 00:10:50 now that nosql thing means that this
- 00:10:53 kind of database
- 00:10:54 enforces no schema so you can have
- 00:10:56 different documents with different
- 00:10:58 pieces of information
- 00:10:59 in the same table or collection as it is
- 00:11:02 called here
- 00:11:03 and it also doesn't really work with
- 00:11:05 relations you will see in this course
- 00:11:07 that we can kind of relate different
- 00:11:09 documents with each other
- 00:11:11 but in general it's way less strict and
- 00:11:14 flexible regarding relations
- 00:11:15 than a sql database is a nosql database
- 00:11:19 is more about storing
- 00:11:20 multiple unstructured documents though
- 00:11:23 you can get some structure into it
- 00:11:25 and we will actually do that in this
- 00:11:26 course i'll come back
- 00:11:28 to what exactly mongodb is and how it
- 00:11:30 works in the respective sections no
- 00:11:32 worries
- 00:11:33 now last but not least it's easily
- 00:11:35 connected to node that's pretty cool
- 00:11:37 it's very easy to integrate or node
- 00:11:39 express to be precise
- 00:11:41 and we don't connect it to angular i
- 00:11:43 already said this theoretically you
- 00:11:44 could find a way
- 00:11:45 but you don't want to do that because
- 00:11:47 you don't want to expose your database
- 00:11:49 credentials
- 00:11:50 in your browser site code which can
- 00:11:52 easily be viewed by the user
- 00:11:54 it's accessible in the developer tools
- 00:11:56 of the browser
- 00:11:58 so mongodb is a powerful database which
- 00:12:01 can easily be integrated into a node
- 00:12:03 express environment and it's very
- 00:12:05 popular these days because it's
- 00:12:07 very flexible and it's highly scalable
- 00:12:11 it's able to handle a large amount of
- 00:12:13 throughput
- 00:12:14 so requests per second or right actions
- 00:12:17 per second and read actions per second
- 00:12:19 and we'll dive deeper into this in the
- 00:12:22 sections where we start working with it
- 00:12:24 now you could theoretically
- 00:12:26 replace it with a different database you
- 00:12:28 could use a sql database in a node
- 00:12:31 express angular application too
- 00:12:32 you're not limited to mongodb and it
- 00:12:35 just wanna really emphasize this
- 00:12:38 i'm using mongodb because it's part of
- 00:12:40 this popular mean
- 00:12:41 stack and it has some advantages but
- 00:12:44 depending on the application and the
- 00:12:46 type of data you're storing
- 00:12:47 if it's a data with a lot of relations
- 00:12:50 maybe a sql database
- 00:12:52 might be better and whilst we will use
- 00:12:54 mongodb in this course i just want to
- 00:12:56 highlight
- 00:12:56 this is not a must you could use any
- 00:12:59 database here
- 00:13:00 the core logic will dive in release the
- 00:13:02 connection of
- 00:13:03 angular and node so with that
- 00:13:06 let me quickly come back to what exactly
- 00:13:08 that single page application thing meant
- 00:13:11 and how the big picture of such a mean
- 00:13:13 app looks like
- 00:13:14 before we start diving into our setup of
- 00:13:17 the course
- 00:13:17 and start building our min app
- 00:13:28 now as i said in this course we'll build
- 00:13:31 a single page
- 00:13:32 application with angular now what is
- 00:13:34 that what is a single page application
- 00:13:37 well in an angular app we'll have one
- 00:13:40 root html file a so-called index html
- 00:13:44 file
- 00:13:44 and we will serve that from our node
- 00:13:47 server or from a different server that's
- 00:13:49 important it can be totally decoupled of
- 00:13:52 our node backend
- 00:13:53 and it actually will be and this html
- 00:13:57 page
- 00:13:58 basically includes some script imports
- 00:14:00 that houses our
- 00:14:01 angular app so the angular framework and
- 00:14:04 our own code
- 00:14:06 and we use that application to
- 00:14:08 dynamically
- 00:14:10 re-render what the user sees without
- 00:14:12 ever
- 00:14:13 requesting a second page to be rendered
- 00:14:15 by
- 00:14:16 the server why because by having this
- 00:14:19 pattern we never need to reload the page
- 00:14:22 just because the user maybe clicked on a
- 00:14:24 post and want to see the details
- 00:14:26 we can instead navigate to that page
- 00:14:29 directly because we don't really leave
- 00:14:30 the page we just
- 00:14:32 remove some elements from the dom and
- 00:14:34 add new elements
- 00:14:35 and all of that is handled for us by the
- 00:14:37 angular framework it's
- 00:14:38 really convenient to use and to work
- 00:14:40 with the dom with it
- 00:14:42 and therefore we have a powerful way
- 00:14:45 of immediately changing the page maybe
- 00:14:47 showing a spinner whilst we're fetching
- 00:14:49 some data behind the scenes so that list
- 00:14:51 of posts which we
- 00:14:52 probably still need to get but we will
- 00:14:54 do that behind the scenes
- 00:14:56 and this provides a highly interactive
- 00:14:59 mobile app-like feeling
- 00:15:01 a very responsive and fast web page
- 00:15:03 where we never have to wait where things
- 00:15:05 always
- 00:15:06 happen and that of course is a great
- 00:15:08 user experience and this is why we will
- 00:15:10 use
- 00:15:10 javascript and angular therefore for the
- 00:15:13 entire front end for the entire user
- 00:15:15 interface
- 00:15:16 and we will use node express and mongodb
- 00:15:18 as a backend to which we
- 00:15:20 reach out behind the scenes to fetch
- 00:15:23 data
- 00:15:23 and send data but the whole user
- 00:15:26 interface
- 00:15:27 is handled as one page only which is
- 00:15:30 dynamically re-rendered
- 00:15:31 all the time by angular
- 00:15:42 with that let's have a look at the big
- 00:15:43 picture how does the entire mean stack
- 00:15:46 look like in this course or in general
- 00:15:48 not just in this course
- 00:15:50 we have the client side and the server
- 00:15:51 side that's important client side is
- 00:15:53 what the user sees
- 00:15:54 the web page as it runs in the browser
- 00:15:56 server side is somewhere on a server we
- 00:15:58 deploy
- 00:15:59 where we run our business logic and
- 00:16:02 which the user only indirectly accesses
- 00:16:05 we'll see how that access works in a
- 00:16:06 second so on the client we use
- 00:16:09 angular which is a javascript framework
- 00:16:11 so we also use javascript implicitly
- 00:16:14 and we use a tube build that user
- 00:16:16 interface
- 00:16:17 on the server side we use node express
- 00:16:20 and mongodb node express for the logic
- 00:16:23 and mongodb as a database as i said you
- 00:16:26 don't want to connect directly to it
- 00:16:28 from angular now the client side angular
- 00:16:32 is responsible for
- 00:16:33 the user interface so for the
- 00:16:34 presentation it's a single page
- 00:16:36 application as i explained in the last
- 00:16:38 lectures
- 00:16:39 and that single page application can be
- 00:16:42 rendered
- 00:16:43 by our node backend so we could have one
- 00:16:45 route which essentially returns that
- 00:16:47 single html page
- 00:16:49 but it can also be totally decoupled
- 00:16:51 from that and be served from a totally
- 00:16:53 different host some static host like aws
- 00:16:56 s3 for example now on the node
- 00:17:00 application
- 00:17:01 we have our core business logic
- 00:17:03 especially the logic that should not be
- 00:17:05 exposed
- 00:17:05 to the client due to security reasons or
- 00:17:08 performance reasons
- 00:17:10 we have our persistent data storage so
- 00:17:13 that database
- 00:17:15 and we also put our authentication logic
- 00:17:17 there for example
- 00:17:18 it's of course part of our business
- 00:17:20 logic i just want to really emphasize
- 00:17:21 that here
- 00:17:22 the logic where we decide whether an
- 00:17:25 email and a password
- 00:17:26 is valid happens on the server because
- 00:17:29 it can easily be fiddled with on the
- 00:17:31 client not so much
- 00:17:32 on the server how do we connect the two
- 00:17:35 pieces then
- 00:17:36 well we exchange requests and responses
- 00:17:39 and these requests and responses are
- 00:17:41 sent behind the scenes
- 00:17:43 so-called ajax requests you might have
- 00:17:46 heard of this before
- 00:17:47 and we use exactly the same pattern in
- 00:17:49 angular
- 00:17:50 these are requests which can be sent
- 00:17:52 without us needing to reload the page
- 00:17:54 which is of course exactly what we want
- 00:17:56 therefore the type of data we exchange
- 00:17:59 is not html
- 00:18:00 because we never want html code we do
- 00:18:03 all that
- 00:18:04 presentation and re-rendering logic with
- 00:18:06 angular instead what we get is so-called
- 00:18:08 json data that's a data format that's
- 00:18:11 really efficient for encoding
- 00:18:13 data like a list of posts and you will
- 00:18:16 see how it looks like in this course
- 00:18:18 this is the big picture this is how the
- 00:18:20 mean stack works and this is exactly
- 00:18:21 what we will
- 00:18:22 implement in this course so with that
- 00:18:24 i'd say enough of the words
- 00:18:26 let's get started and let's start
- 00:18:28 setting up the
- 00:18:30 base development environment we'll work
- 00:18:32 within this course
- 00:18:33 and let's start building our mean stack
- 00:18:40 application
- 00:18:45 so for this course we will need a couple
- 00:18:47 of tools and
- 00:18:48 we'll install and add them step by step
- 00:18:50 for example mongodb will be added a bit
- 00:18:52 later
- 00:18:54 what we'll definitely need is node.js
- 00:18:56 for one
- 00:18:57 because we will write and run node.js
- 00:19:00 code
- 00:19:00 our server-side logic but also because
- 00:19:03 even angular needs it even if we were
- 00:19:06 not to create our own node app not
- 00:19:08 because
- 00:19:09 angular uses node.js language features
- 00:19:12 but because angular actually is a
- 00:19:15 framework that has a more complex
- 00:19:17 build workflow so the part where we take
- 00:19:20 our
- 00:19:20 source code as we write it as a
- 00:19:22 developer and transform it into code
- 00:19:24 that runs fine in the browser
- 00:19:26 that's a bit more complex with angular
- 00:19:28 because angular for one uses
- 00:19:30 typescript a superset to javascript
- 00:19:33 so a different language that's heavily
- 00:19:35 based on javascript
- 00:19:36 and that's important that does not run
- 00:19:39 in the browser
- 00:19:40 and to make it run we need to compile it
- 00:19:42 and it will be done for us no worries
- 00:19:44 but that taskrunner doing the
- 00:19:47 compilation
- 00:19:48 in the end is nodejs for example so this
- 00:19:51 will run
- 00:19:51 all throughout the development process
- 00:19:54 we won't need to write any code for that
- 00:19:56 but this is some stuff that happens
- 00:19:58 behind the scenes and not just the
- 00:19:59 typescript to javascript compilation
- 00:20:01 the angular code itself needs to be
- 00:20:04 bundled and optimized
- 00:20:06 and we need to reduce the code size by
- 00:20:09 stripping out unused code and minifying
- 00:20:11 it
- 00:20:11 and all these are tasks handled by
- 00:20:13 node.js
- 00:20:14 on our machine whilst we are developing
- 00:20:17 the application or
- 00:20:18 when we are finishing it up basically
- 00:20:21 and nodejs will be used for that too so
- 00:20:23 we need it for these two reasons
- 00:20:24 for the node.js code we write for our
- 00:20:27 backend
- 00:20:28 and for the angular build workflow and
- 00:20:30 to learn more about angular and the
- 00:20:31 angular workflow
- 00:20:32 and how it works definitely check out a
- 00:20:35 course dedicated to angular
- 00:20:37 because whilst they will cover some
- 00:20:38 angular basics in this course
- 00:20:40 in general i do expect you to know the
- 00:20:42 very basics about angular this is not a
- 00:20:44 course for you
- 00:20:45 if you never touched angular before so
- 00:20:48 with that out of the way
- 00:20:49 download node.js from nodejs.org
- 00:20:53 and there pick the latest version 10.1
- 00:20:55 in my case
- 00:20:57 if you're facing issues with that fall
- 00:20:59 back to the older version but in general
- 00:21:01 it's recommended to use 10.1 or whatever
- 00:21:04 the latest version is when you're
- 00:21:05 viewing this
- 00:21:06 simply click on that and it will
- 00:21:07 download an installer through which you
- 00:21:09 can walk
- 00:21:09 it's available for both mac os and
- 00:21:12 windows and also linux and it should
- 00:21:14 automatically give you the right
- 00:21:15 download
- 00:21:16 there and once you successfully
- 00:21:18 installed it through the installer
- 00:21:20 we can think about setting up an angular
- 00:21:23 application because that is actually
- 00:21:24 what we'll start with in this course
- 00:21:26 for that we'll use another tool and
- 00:21:28 that's the angular cli
- 00:21:30 cli stands for command line interface
- 00:21:33 and it's the defacto way of creating
- 00:21:35 angular apps
- 00:21:36 because of that more complex build
- 00:21:38 workflow i mentioned
- 00:21:40 we need a lot of tools that compile our
- 00:21:43 code
- 00:21:43 optimize it and setting all of that up
- 00:21:46 on our own is pretty cumbersome and
- 00:21:48 error prone
- 00:21:49 dcli gives us a project setup where all
- 00:21:51 of that is taken care of
- 00:21:53 and where we can focus on writing our
- 00:21:55 angular code
- 00:21:56 our logic dcli is installed like this
- 00:21:59 and it uses npm the node package manager
- 00:22:02 to install the cli tool globally on our
- 00:22:05 machine
- 00:22:06 with this first command here npm the
- 00:22:08 node package manager
- 00:22:10 is installed together with node.js
- 00:22:12 automatically so if you installed
- 00:22:14 node.js you will have npm
- 00:22:16 now let's therefore now install the cli
- 00:22:19 i already got nodejs installed so i can
- 00:22:21 just fast forward to this step
- 00:22:23 and to install the cli you should open
- 00:22:26 your
- 00:22:26 terminal or command prompt on your
- 00:22:29 machine
- 00:22:30 and then run npm this node package
- 00:22:32 manager command which is available with
- 00:22:34 node.js
- 00:22:35 install g for globally because we want
- 00:22:39 to install
- 00:22:40 that angular cli globally on our machine
- 00:22:42 so that we can use it from anywhere on
- 00:22:44 our machine
- 00:22:45 and then the name of that cli package is
- 00:22:48 at
- 00:22:48 angular slash cli and make sure to not
- 00:22:51 mistype this the naming is important
- 00:22:54 you can add a add latest to
- 00:22:57 absolutely fetch the latest version but
- 00:22:59 it should by default give you that
- 00:23:01 version
- 00:23:01 now on windows this command should be
- 00:23:03 fine like this on mac and linux
- 00:23:05 you might need to add a pseudo in front
- 00:23:07 of this to get the right permissions to
- 00:23:09 execute this command
- 00:23:10 hit enter thereafter and enter your
- 00:23:12 password if you are prompted for it
- 00:23:15 and thereafter it will download that cli
- 00:23:17 package from
- 00:23:18 npm's repository and install it on your
- 00:23:21 machine
- 00:23:22 this can take a couple of seconds up two
- 00:23:24 minutes and i'll be back once it's done
- 00:23:26 so it's done installing and in my case i
- 00:23:28 got some errors in between
- 00:23:30 but that's no problem as long as it
- 00:23:32 finishes with some output where it
- 00:23:34 mentions the package name and
- 00:23:36 version and says updated or added eight
- 00:23:39 or
- 00:23:39 the number can actually differ packages
- 00:23:42 so if you see something like that
- 00:23:44 it succeeded you may ignore any errors
- 00:23:46 that happened in between
- 00:23:47 it was able to recover from these now
- 00:23:50 once this is installed
- 00:23:51 we can create a new angular project with
- 00:23:54 dcli
- 00:23:54 and we'll add node and mongo and express
- 00:23:58 to that project setup throughout the
- 00:23:59 course but let's start with the front
- 00:24:01 end because that is how we can quickly
- 00:24:03 see something on the screen
- 00:24:05 so let's create a new project and for
- 00:24:07 that navigate into the folder where you
- 00:24:08 want to create the project
- 00:24:10 once you're in that folder and you can
- 00:24:12 get there with the cd command on your
- 00:24:14 machine
- 00:24:15 create a new project with ng new that is
- 00:24:18 a command now available due to that cli
- 00:24:20 package
- 00:24:21 ng is basically a command made available
- 00:24:24 by that
- 00:24:25 and then the name of the project and i
- 00:24:27 will name it mean
- 00:24:28 course but of course you can pick any
- 00:24:29 name you want just make sure it's not
- 00:24:32 starting with a number
- 00:24:33 and it's not named test that is
- 00:24:35 forbidden but anything else is fine
- 00:24:37 mean course should work and once you hit
- 00:24:40 enter
- 00:24:40 it will set up that project it will
- 00:24:42 create a lot of files in there
- 00:24:44 most of them are configuration files for
- 00:24:46 that workflow we don't need to worry
- 00:24:47 about them
- 00:24:48 and it will also give us a little dummy
- 00:24:50 app with which we can start
- 00:24:52 it will also install all the
- 00:24:53 dependencies like the angular framework
- 00:24:56 and other dependencies that framework
- 00:24:58 depends on but also a couple of
- 00:25:00 build or workflow dependencies
- 00:25:03 so dependencies that compile the
- 00:25:05 typescript code
- 00:25:06 dependencies that optimize the code
- 00:25:09 things like that
- 00:25:10 so this can take a while and i'll be
- 00:25:11 back once it's done
- 00:25:13 now once it is done you can navigate
- 00:25:15 into that newly created folder
- 00:25:17 with cd and then the name of that folder
- 00:25:20 and in there
- 00:25:20 simply run ng-serve to bring up
- 00:25:24 a development only server and this is
- 00:25:27 not a server you will use to deploy it i
- 00:25:29 will show you how to deploy that app
- 00:25:30 towards the end of the course this is a
- 00:25:32 development only server that allows you
- 00:25:34 to preview your application
- 00:25:36 double clicking on the index.html file
- 00:25:38 won't work because that will use the
- 00:25:40 file protocol and not the http protocol
- 00:25:43 and therefore many features we need are
- 00:25:45 not enabled
- 00:25:46 and this gives us a real web server
- 00:25:48 running on our machine
- 00:25:50 at this address you see here http
- 00:25:52 localhost 4200 by default
- 00:25:55 and you can then go to a browser and
- 00:25:57 simply visit localhost
- 00:25:59 4200 and on that url
- 00:26:02 you should see something like this some
- 00:26:04 dummy starting page
- 00:26:06 dcli gives you by default now with that
- 00:26:10 setup we of course want to work on our
- 00:26:12 code
- 00:26:13 and for that we need some ide or some
- 00:26:16 advanced text editor that makes that
- 00:26:18 easier
- 00:26:19 now you can use any id you want like
- 00:26:21 sublime atom
- 00:26:23 webstorm in this course i will use
- 00:26:25 visual studio code
- 00:26:27 now let's set it up and open our project
- 00:26:30 in the next lecture
- 00:26:39 so in the last lecture we created our
- 00:26:41 angular application
- 00:26:43 and now we want to edit it as i
- 00:26:44 mentioned for this we want to use an ide
- 00:26:47 or some advanced text editor because
- 00:26:49 that simply makes working with our code
- 00:26:51 much easier
- 00:26:52 in this course i will use visual studio
- 00:26:54 code and that code part is important
- 00:26:57 not visual studio visual studio code
- 00:27:00 it's a free ide
- 00:27:01 totally free it's pretty powerful it's
- 00:27:03 highly extensible
- 00:27:04 it's awesome and it's available for mac
- 00:27:07 but also for windows
- 00:27:08 linux you can pick your installer
- 00:27:10 version here
- 00:27:11 if it doesn't auto select the right one
- 00:27:13 automatically simply download it then
- 00:27:16 and walk through the installer it gives
- 00:27:17 you there should be nothing special
- 00:27:19 about that
- 00:27:20 and once you got it installed open it if
- 00:27:22 you open it
- 00:27:23 it should look something like this you
- 00:27:24 probably see that welcome page
- 00:27:26 and there you can click open folder to
- 00:27:29 open that
- 00:27:29 angular project we created with the cli
- 00:27:32 a few seconds ago
- 00:27:33 if you don't see that page you can
- 00:27:34 always open it through file open
- 00:27:37 now let's click open folder and navigate
- 00:27:39 to the folder here i selected that mean
- 00:27:41 course project and i can click open now
- 00:27:44 and this loads it into this id so that
- 00:27:46 we can work on it there
- 00:27:47 now the idea might look a bit different
- 00:27:49 for you maybe it doesn't have this dark
- 00:27:51 theme it probably has different icons
- 00:27:54 and that is simply something i
- 00:27:55 fine-tuned for myself so i like this
- 00:27:58 way of it looking and working and i will
- 00:28:01 show you how to get there
- 00:28:02 if you're using a different id you of
- 00:28:04 course have to fine tune it on your own
- 00:28:06 for visual studio code i want to install
- 00:28:09 a certain
- 00:28:10 extension first of all two extensions to
- 00:28:12 be precise
- 00:28:13 and for that go to view extensions
- 00:28:16 you might also see a bar on the left
- 00:28:18 where you can click on extensions icon
- 00:28:21 and on this page make sure to install
- 00:28:23 angular essentials
- 00:28:24 now here i already got that installed
- 00:28:27 you can search for
- 00:28:28 angular here and you should quickly find
- 00:28:31 the angular essentials package
- 00:28:32 search for angular essentials otherwise
- 00:28:35 and that's a pretty amazing collection
- 00:28:37 of different extensions that enhance the
- 00:28:39 ide to work better with angular
- 00:28:42 so simply install this with the install
- 00:28:44 button and feel free to skip or read
- 00:28:46 through the documentation here to find
- 00:28:48 out what's included and how it works
- 00:28:50 besides that i use one other extension
- 00:28:53 which
- 00:28:53 is purely optical it's the material
- 00:28:58 icon theme here so by searching for
- 00:29:00 material you should find it
- 00:29:03 also install this if you like the way my
- 00:29:05 icons look in this course
- 00:29:06 it's purely visual it gives you nicer
- 00:29:08 file icons
- 00:29:09 and i quite like these so with that you
- 00:29:12 can go back to view explorer once you're
- 00:29:14 done
- 00:29:14 and you should see something like this
- 00:29:17 well i also use a dark theme
- 00:29:19 and you can get that same look by going
- 00:29:20 to the code thing here
- 00:29:22 preferences and there color theme
- 00:29:25 and here i'm using dark plus
- 00:29:28 by default you probably are using light
- 00:29:30 plus or light
- 00:29:32 now you can try out these different
- 00:29:34 themes here by simply clicking on them
- 00:29:35 you can always switch
- 00:29:36 and choose the style you like now with
- 00:29:38 that you get the same setup as i do
- 00:29:41 now let's get started working on our
- 00:29:43 angular app
- 00:29:44 this is the folder the angular cli
- 00:29:46 created for us
- 00:29:47 time to edit it
- 00:29:57 so let's quickly start working on the
- 00:29:59 angular app we created
- 00:30:00 this is the folder dcli gave us and as
- 00:30:03 you can see it has a bunch of subfolders
- 00:30:05 and files
- 00:30:06 as i said most of these files are purely
- 00:30:09 for configuration and we don't need to
- 00:30:11 worry about them
- 00:30:12 the package.json file is interesting
- 00:30:14 because here you can see all the
- 00:30:16 dependencies
- 00:30:17 and development only dependencies of the
- 00:30:19 project and later once we
- 00:30:21 start adding some mongodb related
- 00:30:24 dependencies we'll also see them here
- 00:30:26 we got files for configuring the
- 00:30:28 typescript compilation and you don't
- 00:30:30 need to worry about that the defaults
- 00:30:31 are fine we get the angular json file
- 00:30:34 which is for the angular cli
- 00:30:36 and we also don't need to worry about
- 00:30:37 this file in the course for now
- 00:30:39 then e2e is for end to end testing we
- 00:30:42 won't cover this here
- 00:30:43 node modules actually stores all these
- 00:30:46 dependencies which are listed here so
- 00:30:48 they are installed into that folder so
- 00:30:50 that they are available to the project
- 00:30:52 and you can always recreate that folder
- 00:30:54 by running
- 00:30:54 npm install inside this project folder
- 00:30:58 in the terminal this will read the
- 00:30:59 package.json file
- 00:31:01 and download and install them all into a
- 00:31:03 newly created node modules folder
- 00:31:06 and the source folder is where our
- 00:31:08 angular application lives in
- 00:31:10 here we got even more config files which
- 00:31:12 we can safely ignore
- 00:31:14 and then we got this app folder here
- 00:31:17 now there we write the meat of our
- 00:31:20 angular application
- 00:31:21 angular actually uses components i'll
- 00:31:24 come back to that
- 00:31:25 in the next section and we create our
- 00:31:27 whole application by composing our ui
- 00:31:30 from such components therefore if you
- 00:31:32 have a look at that app component
- 00:31:34 html file you can see what we see on the
- 00:31:37 screen here
- 00:31:38 this is actually the content we see here
- 00:31:41 with some dynamic content here and as i
- 00:31:43 said i won't dive deeply into all the
- 00:31:45 basics of
- 00:31:45 angular but a brief refresher will be
- 00:31:47 given in the next course section
- 00:31:49 and if we change this page here and for
- 00:31:52 example say
- 00:31:53 our first app and we save that and
- 00:31:56 ng server is still running that's
- 00:31:58 important it will automatically
- 00:32:00 recompile and reload this page without
- 00:32:02 us doing anything
- 00:32:04 but again make sure that the ng-surf
- 00:32:05 process here is
- 00:32:07 still up and running you can quit it
- 00:32:09 with ctrl c
- 00:32:10 but you should only do so once you're
- 00:32:12 done with developing for the day
- 00:32:14 when you are developing it has to run so
- 00:32:16 that it watches your changes
- 00:32:18 recompiles the code and reloads that
- 00:32:20 page
- 00:32:21 and this is the front and we'll work
- 00:32:23 with we'll add more components
- 00:32:25 we'll compose a complex ui with it and
- 00:32:28 we'll start working with angular here
- 00:32:31 now again i'll walk you through that
- 00:32:32 project and how angular works
- 00:32:34 in a brief summary in the next section
- 00:32:37 for now
- 00:32:38 let's leave it at this little change
- 00:32:40 here so that we can see that we were
- 00:32:41 able to do something
- 00:32:42 just one more word i said that we create
- 00:32:45 a single page application
- 00:32:46 and you can actually see that single
- 00:32:48 page here this
- 00:32:50 index.html file in the source folder
- 00:32:52 this is the file
- 00:32:53 served by ngserv right now or by
- 00:32:56 your favorite host towards the end of
- 00:32:58 the course we will deploy the app
- 00:33:00 together
- 00:33:01 this actually doesn't contain a lot of
- 00:33:03 content for one because the script
- 00:33:06 imports are
- 00:33:07 injected by our build workflow i said
- 00:33:10 that we have quite an
- 00:33:11 elaborate build workflow and it will
- 00:33:13 actually take our optimized angular app
- 00:33:15 create the output files and inject them
- 00:33:18 in there we don't see this during
- 00:33:20 development because it happens in memory
- 00:33:22 but this is what will happen
- 00:33:23 we see it has one html element in the
- 00:33:26 body
- 00:33:27 and that actually is not a default html
- 00:33:29 element
- 00:33:30 that is our custom component you can see
- 00:33:33 it here
- 00:33:34 on the selector this is how angular
- 00:33:37 works and how
- 00:33:38 we take control over the ui with angular
- 00:33:40 and how we can then start composing our
- 00:33:43 ui with angular components
- 00:33:45 and now with that i'd say let's continue
- 00:33:47 and let's find out what's in this course
- 00:33:49 for you
- 00:33:50 before we start diving deeper into
- 00:33:52 angular and building that whole
- 00:33:54 mean stack from ground
- 00:34:04 so now that we know what the mean stack
- 00:34:06 is and that we have our basic
- 00:34:08 project set up for this course let's see
- 00:34:11 what else is inside of this course
- 00:34:13 so we're pretty much done getting
- 00:34:15 started in the next course module
- 00:34:18 we'll dive into building the angular
- 00:34:20 front end you'll get an
- 00:34:21 angular refresher there too though i
- 00:34:24 also recommend diving into some
- 00:34:25 dedicated angular resources
- 00:34:27 just as for node and express and mongodb
- 00:34:30 if you want to learn more
- 00:34:31 but with that we'll build the core
- 00:34:33 foundation the things we can see or will
- 00:34:35 at least start building these
- 00:34:37 in that module thereafter we'll already
- 00:34:40 attach our back end the node express
- 00:34:42 backend so that we can actually do more
- 00:34:45 than just display a beautiful ui well
- 00:34:48 and we also want to work with data and
- 00:34:50 want to store and fetch that data and
- 00:34:52 for that we obviously need a database
- 00:34:54 so in the module thereafter we'll add
- 00:34:56 mongodb to the party
- 00:34:58 and therefore a really great database
- 00:35:00 i'll show you how to add it and how to
- 00:35:02 work with it
- 00:35:02 from node express and therefore also
- 00:35:05 from angular
- 00:35:06 once we did that we'll enhance our app
- 00:35:09 now that's a very broad
- 00:35:10 term but we'll add some things to the
- 00:35:12 angular app to the node backend to turn
- 00:35:14 this into a more
- 00:35:15 realistic and better app so this will be
- 00:35:18 a really important module
- 00:35:20 thereafter we'll already dive into image
- 00:35:23 upload
- 00:35:23 that's a super interesting topic which i
- 00:35:25 was often asked about in my other
- 00:35:27 courses
- 00:35:28 here we got it here you will learn how
- 00:35:30 to let the user
- 00:35:32 select the image in your angular app and
- 00:35:34 then upload it
- 00:35:35 to your node express server and store it
- 00:35:37 there and how to then also of course
- 00:35:39 retrieve it
- 00:35:40 we'll thereafter have a look at another
- 00:35:42 very popular topic
- 00:35:43 pagination we get a lot of data in our
- 00:35:46 database
- 00:35:46 and we typically don't want to fetch all
- 00:35:48 that data in one block
- 00:35:50 that is typically not what you want to
- 00:35:52 do because it impacts performance
- 00:35:54 is more data to download so here i will
- 00:35:57 show you
- 00:35:58 how you can add pagination so how you
- 00:36:00 can select
- 00:36:01 chunks slices of your data to display on
- 00:36:04 a given page
- 00:36:05 and thereafter we'll dive into
- 00:36:07 authentication how can we add users
- 00:36:10 sign up log in and how do we store the
- 00:36:12 information whether a certain user is
- 00:36:14 logged in in our client-side app and use
- 00:36:17 it to reach protected resources on the
- 00:36:19 server
- 00:36:21 thereafter we'll dive into something
- 00:36:23 which is kind of related to
- 00:36:24 authentication authorization
- 00:36:27 authorization is about ensuring that
- 00:36:30 only users who created a post let's say
- 00:36:34 can edit and delete that post so we'll
- 00:36:36 add this
- 00:36:37 in this module we're nearing the
- 00:36:40 end of the course thereafter and we'll
- 00:36:42 dive into error handling
- 00:36:45 what does this mean and how could we
- 00:36:47 elegantly handle errors
- 00:36:49 in our angular app once we're done with
- 00:36:52 that
- 00:36:52 we're pretty much done and we'll put
- 00:36:54 some optimizations into place
- 00:36:56 both on the back end and the front end
- 00:36:59 regarding our code our code structure
- 00:37:01 but all
- 00:37:02 regarding performance and finally we'll
- 00:37:04 of course deploy our application
- 00:37:06 actually in two different ways on one
- 00:37:09 server and on multiple servers
- 00:37:11 and i will explain the differences in
- 00:37:13 this module of course
- 00:37:14 and with that we're done and we'll have
- 00:37:16 a complete
- 00:37:17 mean app finished and deployed and
- 00:37:20 i'm very confident that once you finish
- 00:37:23 this course
- 00:37:23 you'll have all the knowledge you need
- 00:37:25 for your next mean project
- 00:37:36 so now that you know the structure of
- 00:37:38 this course the remaining question is
- 00:37:40 how do you get the most out of this
- 00:37:42 course because that
- 00:37:44 is honestly very important to me
- 00:37:46 obviously
- 00:37:47 i strongly recommend watching the videos
- 00:37:50 and watch them
- 00:37:51 in the order i uploaded them because
- 00:37:53 with that order i did my best to ensure
- 00:37:56 that you have a great learning
- 00:37:57 experience and a
- 00:37:59 good learning curve you might need to
- 00:38:02 increase or reduce the playback speed
- 00:38:04 for some videos or
- 00:38:05 pause sometimes because i try to go
- 00:38:09 through the content of this course on
- 00:38:12 average speed i'm not super slow and i
- 00:38:15 try to not be super fast
- 00:38:17 but everyone is different when it comes
- 00:38:19 to this some students want a slower pace
- 00:38:22 some students want a faster pace and
- 00:38:24 really use the tools the udemy video
- 00:38:26 player gives you
- 00:38:27 to adjust this to your needs now
- 00:38:30 watching the videos is great but i
- 00:38:32 always recommend
- 00:38:33 that you code along write the code that
- 00:38:36 i teach you in this course
- 00:38:38 on your own follow along you will find
- 00:38:41 code snapshots provided by me
- 00:38:43 attached to the last lecture of every
- 00:38:45 module so that you can compare
- 00:38:47 your code to mine in case you're facing
- 00:38:49 any errors
- 00:38:50 because that really enhances the way you
- 00:38:53 learn
- 00:38:54 if you code along and as i said use the
- 00:38:56 course resources
- 00:38:58 like these attached code snippets but
- 00:39:00 also the extra links i have in the last
- 00:39:03 lecture of every module
- 00:39:04 to dive deeper to solve errors and to
- 00:39:07 really become a
- 00:39:08 node angular master now finally and
- 00:39:12 that's also important
- 00:39:13 there is a q a section in this course
- 00:39:15 and if you got
- 00:39:16 any course related questions so
- 00:39:18 questions related to the course
- 00:39:20 source code or some logical question
- 00:39:22 about some concept i taught here
- 00:39:24 please post them there i do read and
- 00:39:27 reply there
- 00:39:28 regularly now asking
- 00:39:31 is great but often you can solve issues
- 00:39:34 on your own by googling
- 00:39:36 by comparing code and you can also
- 00:39:39 help other students if you see open
- 00:39:41 questions
- 00:39:42 please all the reply there it can be
- 00:39:45 hard to do that because you're afraid
- 00:39:47 that your
- 00:39:48 answer might be wrong but who cares even
- 00:39:51 if it's wrong
- 00:39:51 then you'll learn again because someone
- 00:39:53 is going to correct you
- 00:39:54 i really want you to interact because by
- 00:39:57 answering
- 00:39:58 you will learn the most asking is easy
- 00:40:01 answering is much harder
- 00:40:02 and it challenges you to think about a
- 00:40:05 problem to come up with a solution
- 00:40:07 and if you want to become a true master
- 00:40:09 definitely dive into questions
- 00:40:11 and answer them that will really help
- 00:40:14 you
- 00:40:14 the most i promise and that is how you
- 00:40:17 should get the most out of the course
- 00:40:19 and really well become a great angular
- 00:40:23 node
- 00:40:23 developer by the end of it
- 00:40:34 welcome to this module now that we're
- 00:40:36 all set up
- 00:40:37 and learned how we set up our ide and
- 00:40:40 create our first
- 00:40:41 angular experience let's dive into our
- 00:40:44 course project
- 00:40:45 now you will learn how the mean stack
- 00:40:47 works on a real project
- 00:40:49 we'll build a simple posting messaging
- 00:40:53 like app where users can
- 00:40:54 create and edit and delete posts and see
- 00:40:57 the posts of other
- 00:40:59 users which they can't edit though so a
- 00:41:02 mini social network we could say this is
- 00:41:04 what we built and
- 00:41:06 we'll actually start with the angular
- 00:41:08 front end
- 00:41:09 so if we have a look at our big picture
- 00:41:11 here on how the mean stack works
- 00:41:14 we're going to focus on the left side
- 00:41:16 here on the client side
- 00:41:18 and the reason for this simply is that
- 00:41:20 by doing that we can see something very
- 00:41:22 quickly
- 00:41:22 the back end holds a lot of logic but we
- 00:41:25 don't see that much of that
- 00:41:27 if we don't have a front end where we
- 00:41:29 can actually render our data
- 00:41:31 and display it so we'll start with the
- 00:41:33 left part because we can always work
- 00:41:35 with some dummy data
- 00:41:36 until we have the real backend added but
- 00:41:39 we get a beautiful ui
- 00:41:40 right from the start so this is what
- 00:41:42 we'll start with in this module
- 00:41:44 and it will also give you a brief
- 00:41:46 reintroduction to angular
- 00:41:48 now i strongly recommend going through a
- 00:41:50 dedicated angular course first
- 00:41:52 this is not a course that teaches you
- 00:41:55 angular from the ground up
- 00:41:56 but i will cover the important basics
- 00:41:59 and briefly refresh them
- 00:42:01 so that we're all on the same page now
- 00:42:03 with that
- 00:42:04 let's jump right into it let's create a
- 00:42:06 new angular project
- 00:42:07 and let's start building our course
- 00:42:10 project with it
- 00:42:19 i'm back in that first angular app we
- 00:42:22 created in the first course module
- 00:42:24 there we haven't changed that much just
- 00:42:27 added this
- 00:42:27 line in the app component and now i will
- 00:42:30 build up on that project and use it for
- 00:42:32 our mean
- 00:42:33 project now first of all let's
- 00:42:36 understand this folder structure a bit
- 00:42:38 better
- 00:42:38 and let's understand how an angular
- 00:42:41 application
- 00:42:42 actually starts for that i need to start
- 00:42:45 it so i'll bring up my terminal
- 00:42:47 integrated into my ide here and run
- 00:42:50 ngserv
- 00:42:50 to start that build process which we
- 00:42:53 should keep on running
- 00:42:54 and which also starts this development
- 00:42:57 server where we can preview our angular
- 00:42:59 application here it is not that
- 00:43:01 spectacular to be honest
- 00:43:03 but we'll add a lot more to it very soon
- 00:43:06 now to understand how it starts let's
- 00:43:09 have a look at its
- 00:43:10 source code actually and if we inspect
- 00:43:13 that source code what we can see is that
- 00:43:15 we don't see a lot do we we got a basic
- 00:43:19 html5 skeleton
- 00:43:21 and then we got a bunch of script
- 00:43:23 imports at the bottom
- 00:43:24 that clearly is important but that's
- 00:43:27 roughly it there is no content on this
- 00:43:30 page and yes our page doesn't have that
- 00:43:32 much content on it
- 00:43:33 it's only our first app but at least
- 00:43:36 this text should be visible right
- 00:43:38 but we don't see that text here instead
- 00:43:40 we just have
- 00:43:41 app root here and this is an important
- 00:43:45 thing
- 00:43:45 this is not a default html tag or
- 00:43:49 element this clearly has to be related
- 00:43:51 to our
- 00:43:52 angular application as do all these
- 00:43:55 script imports down there and that's
- 00:43:58 exactly what's
- 00:43:59 happening if we go back to our
- 00:44:00 application we can clearly see
- 00:44:02 that what we see on the page is the
- 00:44:04 content of the app component html file
- 00:44:07 and that really is important because
- 00:44:08 angular thinks in components and what we
- 00:44:11 do here is
- 00:44:12 we build our own components or you could
- 00:44:15 say
- 00:44:15 our own html elements what we loaded
- 00:44:20 the page we loaded actually was this
- 00:44:22 index.html file
- 00:44:24 and there we see that app root right we
- 00:44:26 covered that before
- 00:44:28 now the script imports are missing here
- 00:44:30 because they're injected
- 00:44:31 but it's this app root element that is
- 00:44:33 loaded and as you already learned
- 00:44:35 this is our own component here is the
- 00:44:37 selector
- 00:44:38 our own html tag we assign so to say
- 00:44:42 so this is how this is roughly connected
- 00:44:44 and the cli in this
- 00:44:46 build process which we have up and
- 00:44:48 running takes our code
- 00:44:50 bundles it up adds all the angular logic
- 00:44:53 from the angular framework to it
- 00:44:54 and therefore creates a bunch of script
- 00:44:56 files which we don't see here because
- 00:44:58 it's loaded in memory for development
- 00:45:00 and injects these script file imports
- 00:45:03 into the index.html file
- 00:45:04 and what's happening there in the end is
- 00:45:07 that this actually then detects this
- 00:45:08 approved element
- 00:45:09 and swaps it with the content of our
- 00:45:12 component
- 00:45:13 and content is not just the visual part
- 00:45:15 the html part
- 00:45:16 it would also be any logic we have here
- 00:45:19 and we will add a lot of logic
- 00:45:21 throughout this course of course
- 00:45:23 so this is how we connect these two
- 00:45:25 things but where is this
- 00:45:27 swapping logic defined where do we
- 00:45:30 tell the browser that this is our own
- 00:45:32 tag so to say
- 00:45:34 well we get two other important files
- 00:45:36 for that the app module
- 00:45:38 is one important file this essentially
- 00:45:40 is a
- 00:45:42 file which is important for angular it
- 00:45:44 defines the features
- 00:45:46 our angular application has because
- 00:45:48 angular thinks
- 00:45:49 in applications and applications are
- 00:45:52 split up in modules or in this case in
- 00:45:54 one module
- 00:45:56 and that module defines the building
- 00:45:58 blocks of our application
- 00:46:00 and components are not the only but
- 00:46:02 probably the most important
- 00:46:04 building block of an angular application
- 00:46:06 and what we're doing here
- 00:46:08 in the zap module is we're declaring the
- 00:46:11 app component
- 00:46:12 this is registering it with angular so
- 00:46:14 now angular is aware of the app
- 00:46:16 component
- 00:46:17 but this alone would only allow us to
- 00:46:19 use that component selector
- 00:46:21 in other angular components not in the
- 00:46:24 index.html file
- 00:46:26 this is allowed by adding it to the
- 00:46:28 bootstrap array two
- 00:46:30 and we typically only have one component
- 00:46:32 in there
- 00:46:33 because we only have one root component
- 00:46:35 in a typical angular application
- 00:46:37 and all other components would be
- 00:46:40 somehow nested
- 00:46:41 in that root component and this is also
- 00:46:43 how we will build
- 00:46:44 our application in this course so we get
- 00:46:47 that bootstrap array which essentially
- 00:46:50 tells angular
- 00:46:51 that it should search the index.html
- 00:46:54 file which
- 00:46:55 is loaded or in general the page in
- 00:46:56 which the angular app is loaded
- 00:46:58 for the app component identified by its
- 00:47:02 selector now the only remaining thing is
- 00:47:06 what actually starts the angular
- 00:47:08 application
- 00:47:09 and that is the content of the main.ts
- 00:47:11 file this is executed first and
- 00:47:13 that is simply how it's defined you
- 00:47:15 don't define that
- 00:47:16 this is what angular does or how the cli
- 00:47:19 packages
- 00:47:20 up our files in the end the code in here
- 00:47:22 will execute first
- 00:47:23 and what we're doing here mainly is
- 00:47:26 executing this line
- 00:47:27 we import a bunch of stuff because for a
- 00:47:29 typescript to use a certain feature in
- 00:47:31 the file we need to import it
- 00:47:32 so the typescript knows where the code
- 00:47:34 for that feature is
- 00:47:36 located and then we have this line here
- 00:47:40 which uses angular feature platform
- 00:47:42 browser dynamic that's a function
- 00:47:44 we execute that it essentially starts
- 00:47:46 the angular application in the browser
- 00:47:48 and angular is a browser side framework
- 00:47:51 so that seems to be important
- 00:47:53 and then we call another function on an
- 00:47:56 object
- 00:47:56 this first function seems to return and
- 00:47:58 that's the bootstrap
- 00:47:59 module function and there we pass a link
- 00:48:02 to our own module
- 00:48:03 the app module which is located in the
- 00:48:05 app module file
- 00:48:07 we pass this as an argument and this
- 00:48:09 essentially tells angular
- 00:48:11 start your angular application and start
- 00:48:13 it with this module in mind
- 00:48:15 so now angular parses these modules
- 00:48:18 though to say
- 00:48:19 registers these components which are
- 00:48:20 declared imports
- 00:48:22 some other modules because there are
- 00:48:24 some modules angular ships with like the
- 00:48:26 browser module which
- 00:48:28 contains some core features of the
- 00:48:30 angular framework
- 00:48:31 and last but not least it detects the
- 00:48:33 bootstrap array
- 00:48:34 and it then looks on the page it's
- 00:48:36 running on for the selector of this
- 00:48:38 component
- 00:48:40 and this is how the angular application
- 00:48:41 starts how it detects the
- 00:48:44 building blocks that make up that
- 00:48:45 application and how we in the end
- 00:48:48 see our first step on the screen because
- 00:48:50 we use our own component
- 00:48:52 which is understood and used by the
- 00:48:54 angular framework
- 00:49:04 i already mentioned that angular thinks
- 00:49:07 in components that components are one of
- 00:49:10 these crucial things you have to
- 00:49:11 understand when working with angular
- 00:49:14 essentially you compose an entire page
- 00:49:16 of these components
- 00:49:18 you build it with these components
- 00:49:20 because the advantage of this is that
- 00:49:22 you have small
- 00:49:23 easily to maintain and manage building
- 00:49:25 blocks for your ui
- 00:49:27 which you can even reuse because some
- 00:49:29 components appear more than once on a
- 00:49:31 page
- 00:49:32 now here is a screenshot from the
- 00:49:34 official angular
- 00:49:35 dot io page and we can easily
- 00:49:39 deconstruct this into different
- 00:49:40 components to understand this way of
- 00:49:43 thinking in components
- 00:49:44 we could think of having a header a
- 00:49:47 brand
- 00:49:48 and some feature component so three
- 00:49:50 sections of the page
- 00:49:52 which are kind of independent from each
- 00:49:53 other and which we can
- 00:49:55 define in their own components so that
- 00:49:57 we can easily manage the code
- 00:49:59 for that given part of the page but we
- 00:50:02 can and we should
- 00:50:03 be even more granular than that we can
- 00:50:06 clearly identify some navigation items
- 00:50:08 in the header
- 00:50:09 and our search and even in the
- 00:50:12 navigation items we could argue
- 00:50:14 that each navigation item on its own is
- 00:50:16 its own component
- 00:50:18 now you can of course go as granular as
- 00:50:21 you want
- 00:50:21 it probably doesn't make sense to wrap a
- 00:50:23 single html element into its own
- 00:50:26 component
- 00:50:26 at least in most cases but if you got a
- 00:50:29 certain part of your ui
- 00:50:31 that really is decoupled from other
- 00:50:34 elements on the ui
- 00:50:35 and that probably also contains some
- 00:50:37 logic like the search here
- 00:50:39 it definitely has some logic like type
- 00:50:42 ahead
- 00:50:43 or filtering or showing some preview
- 00:50:47 so if you got that then you want to put
- 00:50:49 it into its own component
- 00:50:50 so that you can easily manage the code
- 00:50:52 and possibly reuse it
- 00:50:53 that search could be used in other parts
- 00:50:55 of the application too
- 00:50:57 and we can also do that here for the
- 00:50:59 bottom of this screenshot
- 00:51:00 in the feature component now this could
- 00:51:03 be all in one component
- 00:51:04 but maybe we even split that up a bit
- 00:51:06 more because we might want to reuse that
- 00:51:08 image
- 00:51:09 maybe it contains some logic for lazy
- 00:51:11 loading the image and we want to use
- 00:51:12 that on other parts of the page too
- 00:51:15 so as you can see you can go very
- 00:51:18 granular
- 00:51:19 and you probably already knew that if
- 00:51:21 you worked with angular before
- 00:51:23 and we will go granular in this course
- 00:51:25 too we will build
- 00:51:26 our mean stack application the front end
- 00:51:30 of it
- 00:51:30 we will build that with a lot of angular
- 00:51:33 components
- 00:51:34 so let's get started writing some code
- 00:51:36 and let's dive into
- 00:51:37 that component world
- 00:51:47 in this course we'll build an
- 00:51:49 application where users can create posts
- 00:51:52 can read the posts of our users edit
- 00:51:54 their own ones
- 00:51:55 and so on so let's start working on that
- 00:51:58 and we certainly don't want to handle
- 00:51:59 all the logic in one component only
- 00:52:01 because that would quickly explode in
- 00:52:03 size
- 00:52:04 theoretically it would be possible
- 00:52:06 though that's important to understand
- 00:52:08 but i want to create more than one
- 00:52:09 component and we can simply create a new
- 00:52:11 component
- 00:52:12 by going to that app folder this is
- 00:52:14 where you manage your
- 00:52:15 angular app and the parts that make up
- 00:52:18 that app
- 00:52:18 and by adding a new subfolder there you
- 00:52:21 typically put
- 00:52:22 new components or blocks of components
- 00:52:25 into subfolders to keep your code
- 00:52:27 organized now in there
- 00:52:29 i'll create a new component for creating
- 00:52:32 a new post because that sounds like a
- 00:52:33 good start if you want to work with
- 00:52:35 posts we need to be able to create them
- 00:52:37 otherwise reading them will be hard so i
- 00:52:40 will create a new
- 00:52:42 posts subfolder here which should hold
- 00:52:45 all my post related components
- 00:52:47 and since each component typically is
- 00:52:49 made up of more than one
- 00:52:51 file we got a template for the html code
- 00:52:54 and a css file for the styling as well
- 00:52:56 as the typescript file for the logic
- 00:52:58 i'll create yet another subfolder in
- 00:53:00 there to organize the files of a single
- 00:53:02 component in there
- 00:53:03 now this is up to you you could also use
- 00:53:05 a flatter folder structure where you
- 00:53:07 don't use that many subfolders
- 00:53:09 audio the subfolder way here so
- 00:53:12 in here i want to be able to create a
- 00:53:14 new post and i'll name this
- 00:53:16 post dash create because i'll create the
- 00:53:19 post create component in there
- 00:53:22 the file which i create in there is the
- 00:53:23 post create.component.ts file
- 00:53:27 and now the file name theoretically is
- 00:53:28 up to you but
- 00:53:30 it's a convention angular to include dot
- 00:53:32 component in component files
- 00:53:34 or in general include a description of
- 00:53:37 what's in the file in the file name with
- 00:53:39 this dot notation as we do here
- 00:53:41 dot ts is the extension because we use
- 00:53:43 typescript and the part in front of that
- 00:53:45 there you typically use the kebab case
- 00:53:48 so dash
- 00:53:49 separated words for describing which
- 00:53:52 kind of component this is
- 00:53:54 now i got that post create component in
- 00:53:56 there
- 00:53:57 but a component as i said typically is
- 00:53:59 more than just
- 00:54:01 the logic it at least needs a template
- 00:54:03 now theoretically you can also define
- 00:54:05 that
- 00:54:05 html template in this typescript file
- 00:54:08 but since we have a bit of a more
- 00:54:10 complex template
- 00:54:12 and in general it's a good practice to
- 00:54:14 create a separate file
- 00:54:15 so that will be the post create dot
- 00:54:17 component
- 00:54:18 dot html file now so that's the html
- 00:54:21 file belonging to that component and
- 00:54:24 with these two files we can
- 00:54:25 work with that now in the typescript
- 00:54:27 file we create a component by simply
- 00:54:29 creating a new class
- 00:54:31 a class is a typescript feature it's all
- 00:54:33 available in
- 00:54:34 the latest javascript versions it
- 00:54:36 essentially allows us to create
- 00:54:38 a blueprint for an object though we will
- 00:54:40 never create
- 00:54:41 that component object on our own we just
- 00:54:44 give it to angular and angular will
- 00:54:46 instantiate it
- 00:54:47 and create it and use it we just define
- 00:54:50 how such a component would look like
- 00:54:52 and that includes a name for it there
- 00:54:55 the convention is to use basically your
- 00:54:57 file name
- 00:54:58 but now in that notation here post
- 00:55:01 create component
- 00:55:02 so the individual words starting with
- 00:55:04 capital characters
- 00:55:05 and component at the end and we actually
- 00:55:08 as i said create a class here so don't
- 00:55:10 forget the class keyword
- 00:55:11 and now we get a new class which
- 00:55:15 essentially is just a typescript class
- 00:55:17 we turn it into a component angular
- 00:55:19 understands
- 00:55:21 by adding a so-called decorator to it a
- 00:55:23 decorator is a typescript feature
- 00:55:25 you add an add and then the name of the
- 00:55:27 decorator and
- 00:55:28 angular ships with a component decorator
- 00:55:31 to use it in that file you need to
- 00:55:32 import it though
- 00:55:34 so import component from
- 00:55:37 at angular core now this is one of the
- 00:55:40 packages the angular framework is
- 00:55:42 comprised of
- 00:55:43 and this package includes these core
- 00:55:45 features like that component
- 00:55:47 decorator which you attach to a class to
- 00:55:50 mark it
- 00:55:51 as a component which angular then scans
- 00:55:54 for certain features and uses
- 00:55:56 as a component now the component
- 00:55:58 decorator takes some configuration
- 00:56:01 in the form of a javascript object which
- 00:56:03 we pass to it
- 00:56:04 in that object we need to define things
- 00:56:07 like the template
- 00:56:08 so we define a template and if we just
- 00:56:11 use
- 00:56:11 template you could pass a string in here
- 00:56:14 to write some html code here
- 00:56:16 but for longer templates this is not
- 00:56:18 really something you want to do
- 00:56:19 define a template url instead and then
- 00:56:22 add a relative path
- 00:56:24 to your template file so in my case it's
- 00:56:26 post create dot
- 00:56:28 component html so this is then the file
- 00:56:31 while angular will look for the template
- 00:56:34 and then parse
- 00:56:35 so now this is pointing at that html
- 00:56:37 file
- 00:56:38 now with that we also need to add more
- 00:56:41 we
- 00:56:42 want to add a selector let's actually
- 00:56:44 add that first
- 00:56:45 a selector which allows us to use that
- 00:56:47 component
- 00:56:48 so to use it by that selector which
- 00:56:50 serves as our own html tag
- 00:56:53 the convention is to start with app dash
- 00:56:56 to avoid clashes with normal html
- 00:56:59 elements which name you might take
- 00:57:01 otherwise accidentally
- 00:57:03 and then any name you want but typically
- 00:57:05 you also use the
- 00:57:06 well file name or the component name for
- 00:57:08 this so app post create
- 00:57:10 don't forget the comma now this defines
- 00:57:13 a basic
- 00:57:14 component you need a template and you
- 00:57:17 typically also need a selector
- 00:57:18 so that you're able to include it you
- 00:57:21 don't need to add anything in the
- 00:57:22 typescript code here
- 00:57:23 we want to add something in the template
- 00:57:25 so that we can see it
- 00:57:27 maybe a h2 tag the post create
- 00:57:31 component and now what
- 00:57:34 now we could use it we could go to the
- 00:57:36 app component
- 00:57:37 html file because remember all
- 00:57:40 components
- 00:57:40 other than the app component are added
- 00:57:42 to other angular components
- 00:57:44 not the index.html file and in the
- 00:57:47 appcomponent.html file
- 00:57:49 we could add app post create like that
- 00:57:52 this is now our own html tag our own
- 00:57:55 component being used
- 00:57:56 you see my ide already isn't liking this
- 00:57:59 and if we save that and we go back to
- 00:58:02 the application
- 00:58:03 we see a blank screen if we now open the
- 00:58:05 developer tools here in the browser we
- 00:58:08 see that we got an error message
- 00:58:10 that app post create is not a known
- 00:58:12 element
- 00:58:13 the reason for that is that it isn't a
- 00:58:15 known element
- 00:58:16 angular has no way of knowing this
- 00:58:19 because by default
- 00:58:20 angular and also not the build process
- 00:58:23 it doesn't scan all files in our app
- 00:58:25 folder
- 00:58:26 and try to evaluate if it should be
- 00:58:29 aware of that if that
- 00:58:30 is a component instead we explicitly
- 00:58:33 have to register a component
- 00:58:35 if we want to use it and we do that in
- 00:58:37 an angular module
- 00:58:38 in the only module we get thus far in
- 00:58:41 the app module
- 00:58:42 there we add it to declarations and for
- 00:58:45 that we first of all need to import it
- 00:58:47 that's a typescript requirement if you
- 00:58:49 use something in another file you need
- 00:58:51 to tell typescript where the code behind
- 00:58:53 it can be found
- 00:58:54 so we want to import something from
- 00:58:57 posts
- 00:58:57 slash post create slash post create
- 00:58:59 component
- 00:59:00 and you omit the extension so you don't
- 00:59:03 add dot
- 00:59:04 ts here now the something we want to
- 00:59:06 import
- 00:59:07 is the post create component class so a
- 00:59:10 reference to the class to be precise
- 00:59:13 and we store that in the declarations
- 00:59:15 array here so that now angular
- 00:59:17 is aware of this and that is all we need
- 00:59:19 to do now if we save that
- 00:59:22 you see the post create component here
- 00:59:24 and the errors in the ide
- 00:59:26 will also go away as soon as you change
- 00:59:28 something in the respective files
- 00:59:30 and then save again so now we get our
- 00:59:33 first component added
- 00:59:34 that's nice it's not that useful though
- 00:59:37 would be nice if we could use that
- 00:59:39 component to really well
- 00:59:41 create new posts so let's do that in the
- 00:59:44 next lecture
- 00:59:53 we want to create new posts and we got
- 00:59:55 the post create component
- 00:59:56 thus far it only got a title well what
- 00:59:59 do we need
- 01:00:00 to create new posts as a core
- 01:00:03 minimum we need an input and we need a
- 01:00:06 button
- 01:00:07 to save that post right so let's
- 01:00:10 add both in the template of post create
- 01:00:12 a input
- 01:00:13 a normal text input or maybe a text area
- 01:00:17 because we want to be able to enter more
- 01:00:19 text in just one line
- 01:00:21 so let's add a text area now we don't
- 01:00:24 need a name
- 01:00:25 we can omit the id columns we don't need
- 01:00:28 that
- 01:00:28 rows i'll set this to 6 so that's a bit
- 01:00:30 smaller
- 01:00:31 and if we save that we see a text area
- 01:00:35 no styles so it's not that pretty we'll
- 01:00:38 come back to the styling soon let's
- 01:00:39 focus on the logic for now as i said we
- 01:00:42 also need a button so let's add a button
- 01:00:44 below the text area
- 01:00:45 where we say save post like that
- 01:00:49 and now of course this doesn't do
- 01:00:50 anything it looks super ugly
- 01:00:52 let's actually do something about that
- 01:00:54 let's add a horizontal
- 01:00:56 line between the two for now but it's
- 01:00:58 still not pretty but we can work with
- 01:00:59 that
- 01:01:00 so we can click that button but it
- 01:01:01 doesn't do anything we can enter
- 01:01:03 anything here
- 01:01:03 but that of course doesn't create a new
- 01:01:05 post because what's missing
- 01:01:07 the logic well also the styling but
- 01:01:09 mainly the logic
- 01:01:11 how would the browser know what we want
- 01:01:13 to do when we click save post
- 01:01:15 it can't and that is exactly the logic
- 01:01:17 we'll add with angular
- 01:01:19 now to do something upon a click here
- 01:01:22 we need to add a click listener and we
- 01:01:24 do that with a feature called event
- 01:01:26 binding event binding is an angular
- 01:01:29 feature
- 01:01:29 which allows us to listen to events in a
- 01:01:31 declarative way
- 01:01:33 which means instead of using javascript
- 01:01:35 where we would go to our code
- 01:01:37 and then try to select the element with
- 01:01:39 query selector or anything like that
- 01:01:41 and then use add event listener on the
- 01:01:43 element instead of doing all that
- 01:01:45 programmatically
- 01:01:46 we go to our template and we add
- 01:01:49 something there which is not default
- 01:01:51 html but which is understood by angular
- 01:01:53 since this is an angular component we
- 01:01:56 add parentheses
- 01:01:57 and in between there the name of the
- 01:02:00 event we want to listen to
- 01:02:01 and that's now not on click but just
- 01:02:04 click
- 01:02:04 so the name without on and you can of
- 01:02:07 course also listen to things like
- 01:02:09 mouse down mouse enter and so on but
- 01:02:11 here it's click
- 01:02:13 then equal and then quotation marks
- 01:02:16 between which you define the code you
- 01:02:19 want to execute
- 01:02:20 now that can't be complex code here in
- 01:02:22 the template and typically you just pass
- 01:02:24 the name
- 01:02:25 of a method of that component class here
- 01:02:29 which should be executed so we could add
- 01:02:31 a method that's a function in a class
- 01:02:34 to that post create component and i'll
- 01:02:36 simply name it
- 01:02:38 on add post the name is up to you but
- 01:02:41 you typically start with the on at the
- 01:02:43 beginning of your method name
- 01:02:44 for methods that are triggered upon
- 01:02:46 events now in there
- 01:02:48 we want to get information about that
- 01:02:51 new post right
- 01:02:53 and for now what i'll do is i'll just
- 01:02:56 throw an alert
- 01:02:56 post added so that we can see if that
- 01:02:59 worked if we successfully triggered this
- 01:03:02 now i pass this on add
- 01:03:06 post function name here including the
- 01:03:09 parentheses
- 01:03:10 to click what this will do is it will
- 01:03:12 connect both
- 01:03:13 after reloading for click save post we
- 01:03:15 see that alert up here so that worked
- 01:03:19 now that's the first step we are able to
- 01:03:22 listen to events
- 01:03:23 we're not able to get the input we
- 01:03:25 entered here and we're not able to
- 01:03:27 output anything
- 01:03:28 on the screen other than that alert
- 01:03:30 these are the things we'll work on next
- 01:03:41 so before we come to fetching that user
- 01:03:43 input let's
- 01:03:44 output a post let's output some dummy
- 01:03:46 content
- 01:03:47 let's say we have a paragraph there
- 01:03:49 below the button
- 01:03:50 and here we want to output the content
- 01:03:52 the user entered now for now the user
- 01:03:54 didn't enter anything
- 01:03:56 so let's set some dummy content for this
- 01:03:59 we need
- 01:03:59 two things we need to set some content
- 01:04:02 in on ad post and we need a place to
- 01:04:04 store that content in
- 01:04:05 which we then can also refer to from the
- 01:04:07 template
- 01:04:09 that stored the content in thing is a
- 01:04:12 property
- 01:04:13 basically a variable in a class you
- 01:04:16 define it without the var
- 01:04:17 const or let keyword you just add the
- 01:04:20 name
- 01:04:21 in the class here and the name can be
- 01:04:24 anything you like
- 01:04:25 like for example new post
- 01:04:28 now i'll set this to an empty string by
- 01:04:30 default and then
- 01:04:32 on add post i will overwrite it we refer
- 01:04:34 to it with the this keyword
- 01:04:36 this new post and we set this equal to
- 01:04:38 any content you like
- 01:04:40 like the users
- 01:04:43 oops escape that post
- 01:04:46 like that notice that i escaped that in
- 01:04:49 between single quotation mark with a
- 01:04:50 backslash
- 01:04:52 so now we're setting the new post value
- 01:04:54 to this value whenever we click the
- 01:04:56 button
- 01:04:56 now to output the new post we need to go
- 01:04:59 back to the html file
- 01:05:01 and just as we added the listener
- 01:05:03 directly in here
- 01:05:04 we also add output or output
- 01:05:08 hooks directly in the template
- 01:05:11 we do that with a feature called string
- 01:05:14 interpolation
- 01:05:15 and you add or use that feature with
- 01:05:18 double
- 01:05:18 curly braces opening and closing and in
- 01:05:21 between
- 01:05:22 you refer to something which is stored
- 01:05:25 inside your post create component or
- 01:05:28 your
- 01:05:29 component belonging to the template in
- 01:05:31 general that something could be a method
- 01:05:34 and then you would output whatever this
- 01:05:36 method returns
- 01:05:37 or it can be a property name like new
- 01:05:40 post
- 01:05:41 so here i can just say new post and
- 01:05:43 refer to that property
- 01:05:45 and now what you can see is that when i
- 01:05:47 save this
- 01:05:48 you don't see anything because we start
- 01:05:50 with an empty string a new post
- 01:05:52 but if i click save post you see the
- 01:05:54 user's post here
- 01:05:55 because we changed that text and due to
- 01:05:58 string interpolation
- 01:05:59 we told angular hey please output the
- 01:06:01 current value of the text
- 01:06:03 and also when it changes please output
- 01:06:05 the new value
- 01:06:06 in this place here in our html code
- 01:06:10 so that is string interpolation in place
- 01:06:13 and that is one important building block
- 01:06:15 when it comes to
- 01:06:15 outputting content now let's also
- 01:06:18 dive into one other way of outputting
- 01:06:21 content on the screen
- 01:06:22 let's say we want to pre-populate the
- 01:06:25 text area with some dummy starting text
- 01:06:27 let's say we don't start with an empty
- 01:06:30 string here
- 01:06:31 but with no content now of course if i
- 01:06:34 save this
- 01:06:35 it reloads and we have no content here
- 01:06:37 until we click the button
- 01:06:38 and let's say we want to output no
- 01:06:40 content in the text area too
- 01:06:42 now in the text area we can use string
- 01:06:45 interpolation
- 01:06:46 like this new post and if we save that
- 01:06:51 we get no content in there too we could
- 01:06:54 also do something different a text area
- 01:06:56 is an input element
- 01:06:58 in html and as such it has a special
- 01:07:01 property we can bind to
- 01:07:02 not an attribute a property html
- 01:07:05 elements in the dom and in javascript
- 01:07:07 are just javascript objects with a
- 01:07:10 couple of properties so
- 01:07:11 variables belonging to that object which
- 01:07:13 we can read and write
- 01:07:15 and one property is the value property
- 01:07:19 now the value property actually can't be
- 01:07:21 set like this
- 01:07:22 so if we set this to test here
- 01:07:26 you see it's empty but we have another
- 01:07:29 feature in angular which allows us to
- 01:07:30 directly target
- 01:07:32 properties of the underlying objects
- 01:07:35 of the html elements we can add the
- 01:07:39 property name and of course you have to
- 01:07:41 know that this element has a value
- 01:07:43 property
- 01:07:43 but now you do know you can use
- 01:07:45 resources like the mdn the mozilla
- 01:07:47 developer network to get
- 01:07:48 complete references of all available
- 01:07:50 properties of
- 01:07:51 all available elements but if you know
- 01:07:54 that name you can wrap it in
- 01:07:56 square brackets like this and this will
- 01:07:59 now
- 01:07:59 directly target the value property of
- 01:08:02 the underlying object
- 01:08:04 and bind the value between quotation
- 01:08:06 marks to it now important
- 01:08:08 just as for the click listener or for
- 01:08:10 string interpolation
- 01:08:11 this value is now not normal text but
- 01:08:14 actually
- 01:08:14 typescript code so if you enter test
- 01:08:17 here it would look
- 01:08:18 for a property named test in your
- 01:08:20 component
- 01:08:21 if you want to output test as a string
- 01:08:23 you need to wrap this in single
- 01:08:24 quotation marks
- 01:08:26 and now if you save this you see test as
- 01:08:28 a starting value because we're binding
- 01:08:30 to the underlying
- 01:08:32 value property and of course you can
- 01:08:35 also bind this
- 01:08:36 not to a string but to new post now
- 01:08:39 without the single quotation marks
- 01:08:40 because now we want to refer to that
- 01:08:42 property
- 01:08:43 in our component class and now we see no
- 01:08:45 content there too
- 01:08:47 this is important to know we will use a
- 01:08:50 combination of string interpolation for
- 01:08:52 a simple text most of the time if you
- 01:08:54 want to output it between opening and
- 01:08:55 closing tags
- 01:08:56 and property binding always used
- 01:08:59 directly on the elements
- 01:09:00 for outputting data in our template
- 01:09:04 now we can output data that's all cool
- 01:09:06 but how can we now finally get that user
- 01:09:08 input
- 01:09:09 we'll do this in the next lecture
- 01:09:19 so let's get the user input and there
- 01:09:22 actually are two ways of doing that
- 01:09:23 the first one is another feature which
- 01:09:25 is called local reference
- 01:09:28 we can add a marker a variable to
- 01:09:31 any html element we want we do that by
- 01:09:33 adding a hashtag
- 01:09:34 and then any name you want like post
- 01:09:38 input like that now this marks this or
- 01:09:41 it creates a reference
- 01:09:43 to that element which you can use and
- 01:09:45 which you can use and that's important
- 01:09:47 in that template so you can use it for
- 01:09:49 example here to pass data to on add post
- 01:09:52 you could refer to post input like this
- 01:09:54 without the hashtag now
- 01:09:56 and then pass this entire thing
- 01:09:59 so this will now just be a reference to
- 01:10:01 the underlying javascript object
- 01:10:04 in all add post we can take a look at it
- 01:10:06 by
- 01:10:07 expecting it as an argument so there we
- 01:10:09 get the
- 01:10:11 post input and this will actually
- 01:10:14 be an html input we can clearly tell
- 01:10:17 typescript to type by adding a colon
- 01:10:19 then
- 01:10:19 html text area element that is exactly
- 01:10:22 what it is
- 01:10:23 now this just informs typescript about
- 01:10:25 the type here this is great because now
- 01:10:26 we get better
- 01:10:27 auto completion because the ide knows
- 01:10:30 which kind of type that is
- 01:10:32 but it also helps us write cleaner code
- 01:10:34 but i of course only want to do one
- 01:10:36 thing here
- 01:10:37 i want to output the post input like
- 01:10:39 this
- 01:10:40 if we save that and let it reload and
- 01:10:42 have the developer tools
- 01:10:44 open we see that upon saving i get
- 01:10:47 this output now we can't really see
- 01:10:49 what's in there we can't really see the
- 01:10:51 javascript object
- 01:10:52 we can look into that with console.der
- 01:10:55 instead of console.log
- 01:10:57 now if we press save content we get the
- 01:10:59 text area object and here you see all
- 01:11:01 the properties this
- 01:11:02 specific javascript object knows quite a
- 01:11:05 lot as you can see
- 01:11:06 there also is the value property we
- 01:11:08 bound before
- 01:11:10 now of course we cannot just bind the
- 01:11:13 value property since we got
- 01:11:15 access to it here we can also just use
- 01:11:17 it to extract the content
- 01:11:19 and set the content we entered as a
- 01:11:22 value for new post
- 01:11:23 so we can say input dot value to access
- 01:11:27 that value property and now if we save
- 01:11:29 that
- 01:11:30 what we can see is that if we enter
- 01:11:33 something here
- 01:11:34 and i hit save post we see something
- 01:11:36 down there
- 01:11:37 now that really is amazing and this
- 01:11:39 allows us to fetch the user input and
- 01:11:41 output it
- 01:11:42 it's only one way of getting that user
- 01:11:44 input though
- 01:11:45 this is a way which of course allows us
- 01:11:47 to
- 01:11:49 do anything with that element not just
- 01:11:50 get the value but then get the value if
- 01:11:53 that is what we want to do
- 01:11:54 upon a click now another feature angular
- 01:11:57 offers
- 01:11:58 is a feature called two-way binding
- 01:12:01 rather than manually setting the value
- 01:12:03 of the text area
- 01:12:04 and then also getting a reference to it
- 01:12:07 and so on
- 01:12:08 we can get rid of both and actually add
- 01:12:11 a new feature
- 01:12:12 which combines the setting and reading
- 01:12:15 of a value
- 01:12:16 it's called two-way binding because it
- 01:12:18 has this two-directional flow
- 01:12:20 and you add it with square brackets and
- 01:12:22 parentheses
- 01:12:23 and then ng-model in between ng-model is
- 01:12:27 an angular
- 01:12:28 feature it's a so-called directive a
- 01:12:31 directive
- 01:12:32 is basically an instruction you place on
- 01:12:34 an html element
- 01:12:36 in angular or you can also create your
- 01:12:38 own ones so the directive knows what to
- 01:12:40 do on that element then
- 01:12:41 ng model is a directive that actually
- 01:12:43 will listen to user input
- 01:12:44 and emit that data to us and
- 01:12:47 also store new data in that text area
- 01:12:51 or output it there we need to bind it
- 01:12:54 to a property and i will
- 01:12:58 use a new property for that because i
- 01:13:00 don't want to update new post with every
- 01:13:02 keystroke
- 01:13:04 i'll add entered value here it's an
- 01:13:06 empty string initially
- 01:13:08 and entered value this new property is
- 01:13:10 what i bind
- 01:13:11 to ng model now important ng model by
- 01:13:14 default won't work
- 01:13:16 it's a feature which is not included in
- 01:13:18 the core
- 01:13:19 angular package here it's not included
- 01:13:22 in the browser module which we already
- 01:13:24 added
- 01:13:24 it's included in a different module
- 01:13:26 which we need to add
- 01:13:28 it's included in the so-called forms
- 01:13:30 module because it's related to forms
- 01:13:32 inputs
- 01:13:33 and this is part of add angular forms so
- 01:13:36 that's still part of the core framework
- 01:13:38 but of a different part of the framework
- 01:13:40 so importing it here allows typescript
- 01:13:43 to find it
- 01:13:44 angular isn't aware of it yet though it
- 01:13:46 is aware once we add it
- 01:13:47 to the imports array in our app module
- 01:13:50 now we're unlocking some forms features
- 01:13:52 and ng model is one of them so
- 01:13:56 now we can use ng model here and it will
- 01:14:00 automatically update enter value or
- 01:14:02 entered value here
- 01:14:04 with every keystroke and therefore in
- 01:14:06 this new post
- 01:14:07 we no longer receive the post input here
- 01:14:11 instead we simply set new post equal
- 01:14:15 to entered value this entered value
- 01:14:19 back in the template this also means we
- 01:14:20 get rid of post input as an argument
- 01:14:22 here
- 01:14:24 and now if we save that and we go back
- 01:14:26 to our application
- 01:14:28 you see we don't start with no content
- 01:14:30 anymore i can enter
- 01:14:31 something and if i hit save post we see
- 01:14:33 that here too
- 01:14:34 but now we're using that two-way binding
- 01:14:37 feature which can also be very handy
- 01:14:40 these are the core template binding
- 01:14:42 features angular has
- 01:14:44 event binding string interpolation
- 01:14:46 property binding which you sorted before
- 01:14:48 with square brackets value
- 01:14:50 and two-way binding with that we got a
- 01:14:52 lot of tools that allow us to manipulate
- 01:14:54 our components and the
- 01:14:56 output we have and also to react to user
- 01:14:58 events
- 01:15:00 and now with that it's time to leave
- 01:15:01 that world of ugly
- 01:15:03 applications and actually turn this into
- 01:15:06 a pretty one and dive deeper into really
- 01:15:08 building
- 01:15:08 a mean stack project because this is of
- 01:15:10 course no angular basics course
- 01:15:12 but knowing all these basics and
- 01:15:14 refreshing them is really important
- 01:15:16 so that you don't get lost throughout
- 01:15:18 the rest of the course
- 01:15:28 so now that we had this brief refresher
- 01:15:30 on the very basics of angular
- 01:15:32 it's time to work on the real
- 01:15:34 application we're building and we want
- 01:15:35 to build a beautiful application right
- 01:15:37 now we could write all these css styles
- 01:15:39 on our own and write everything from
- 01:15:41 scratch on our own
- 01:15:43 but this is an angular or especially a
- 01:15:45 mean stack guide and i want to focus on
- 01:15:47 these mean stack components and not so
- 01:15:49 much on the styling
- 01:15:50 therefore i'll use angular material
- 01:15:53 which is a package
- 01:15:55 actually also created by parts of the
- 01:15:57 angular team
- 01:15:59 which gives us a set of pre-built
- 01:16:01 angular components and that's important
- 01:16:03 it's not just a styling package it's not
- 01:16:05 like bootstrap
- 01:16:06 it's actually an angular package which
- 01:16:08 ships with a couple of angular
- 01:16:10 components
- 01:16:11 which we can drop into our application
- 01:16:13 now we'll still write all the core logic
- 01:16:15 of our application on our own
- 01:16:17 but all the nitty gritty details and to
- 01:16:19 be honest quite a lot of the styling
- 01:16:22 will be taken care of now this uses
- 01:16:24 google's material design so of course
- 01:16:26 you have to like that
- 01:16:27 to be happy with that but i think it
- 01:16:29 looks quite nice and if we have a look
- 01:16:30 at the components part
- 01:16:32 on material.angular.io we can see it has
- 01:16:35 a bunch of pre-built components
- 01:16:37 that should give us everything we need
- 01:16:39 to build a nice application
- 01:16:40 to include things like a header include
- 01:16:43 things like
- 01:16:44 our buttons our inputs things like that
- 01:16:48 so this is what i want to work with and
- 01:16:50 to add it to our project
- 01:16:52 i'll quit my development server for now
- 01:16:55 and i need to install this so we'll run
- 01:16:56 npm install
- 01:16:58 dash dash save this will install a new
- 01:17:01 dependency into that project
- 01:17:02 npm is that package manager and now it's
- 01:17:06 add angular slash material now don't hit
- 01:17:10 enter yet
- 01:17:11 this is one way of adding it now if
- 01:17:13 you're using the latest cli version
- 01:17:15 which you
- 01:17:16 very likely are cli version 6 plus to be
- 01:17:19 precise
- 01:17:21 then you get a different command
- 01:17:22 available and if you don't use the
- 01:17:24 latest version you can always update by
- 01:17:25 running
- 01:17:26 npm install g at angular cli by the way
- 01:17:30 so if you use that latest version and
- 01:17:32 your project was created with the latest
- 01:17:34 version 2
- 01:17:35 you can run ng add now that's the cli
- 01:17:38 command at angular material and what
- 01:17:42 this will do is
- 01:17:42 it will also install the material
- 01:17:45 package but
- 01:17:46 also already configure your project to
- 01:17:48 include it
- 01:17:49 and i'll of course show you what this
- 01:17:51 means what included
- 01:17:53 actually means and by the way i also got
- 01:17:55 a series on youtube and my webpage which
- 01:17:58 you can check out
- 01:17:59 you'll find a link to it in the last
- 01:18:00 lecture of this module where i
- 01:18:03 give a little bit of a more detailed
- 01:18:04 walkthrough of angular material
- 01:18:06 i also got another course here on udemy
- 01:18:08 where i dive deeper into it
- 01:18:09 in this course this will not be an angle
- 01:18:12 material course
- 01:18:13 i just want to use it and i will
- 01:18:15 therefore just explain
- 01:18:16 the basics you need to know about using
- 01:18:18 it so now it's done
- 01:18:20 setting it up and what it did is in the
- 01:18:22 package.json file
- 01:18:24 it added a new dependency or two new
- 01:18:26 dependencies to be precise
- 01:18:28 angular material this package and the
- 01:18:31 angular cdk
- 01:18:32 now the material package actually split
- 01:18:35 up in two packages you could say
- 01:18:36 one for the logic behind the components
- 01:18:39 and one for the concrete implementations
- 01:18:41 and the styling
- 01:18:42 the cdk is the logic material is then
- 01:18:45 logic plus
- 01:18:46 styling and more on that in that series
- 01:18:49 i just mentioned
- 01:18:50 this is included this is installed as a
- 01:18:52 dependency
- 01:18:54 in the angular json file which
- 01:18:55 configures our project
- 01:18:57 it also did one thing it added this
- 01:19:00 input here this
- 01:19:01 style m here which simply includes a
- 01:19:04 default
- 01:19:05 theme of the material design package
- 01:19:09 indigo pink so that's just some colors
- 01:19:11 that's the styling for all these
- 01:19:13 components and you can actually switch
- 01:19:15 that with another pre-built theme you
- 01:19:17 can see all of them in
- 01:19:18 node modules at angular and then their
- 01:19:21 search for material here
- 01:19:25 and then in material you should find a
- 01:19:26 folder pre-built
- 01:19:28 themes this one and there you see four
- 01:19:32 files
- 01:19:32 indigo pink deep purple amber and so on
- 01:19:35 now we're using
- 01:19:36 indigo pink here and you can always
- 01:19:38 switch this so you can all use purple
- 01:19:40 green
- 01:19:41 deep purple amber i'll stick to this one
- 01:19:43 but you can switch this with one of the
- 01:19:45 other files
- 01:19:46 so this is the styling that is added now
- 01:19:48 what else did
- 01:19:50 the ng add command do for us it edited
- 01:19:54 our app module
- 01:19:56 there it now imports the browser
- 01:19:58 animations module
- 01:19:59 a part of the angular framework because
- 01:20:02 some of these components provided by
- 01:20:04 angular material
- 01:20:05 use animations and therefore this is
- 01:20:07 included too
- 01:20:09 and that's basically it you can also see
- 01:20:11 a log of what it did
- 01:20:12 here so it updated package.json angular
- 01:20:14 json app module
- 01:20:16 styled css now also the index.html file
- 01:20:20 there we can see what it did is it
- 01:20:22 included imports to
- 01:20:24 the material icons so that we can use
- 01:20:26 these icons and the roboto font
- 01:20:28 so that our text actually has the normal
- 01:20:31 material
- 01:20:32 design too so that is what now happened
- 01:20:35 now we can restart
- 01:20:36 ng server we can start using angular
- 01:20:38 material
- 01:20:39 and to use it we actually just need to
- 01:20:42 import what we need
- 01:20:43 and use the component in our template
- 01:20:47 so first of all let's start by pimping
- 01:20:49 that post create component
- 01:20:51 and for that let's look at form controls
- 01:20:53 in the official docs that sounds
- 01:20:54 promising
- 01:20:55 and what we need is some some input
- 01:20:58 right we need some inputs
- 01:20:59 we want to be able to add a text area so
- 01:21:02 we got
- 01:21:03 our input and text area
- 01:21:06 elements which you can use and here
- 01:21:09 if we check out that example code we can
- 01:21:11 also see how such an input is created
- 01:21:14 with the angle material package
- 01:21:16 essentially we add this matte input
- 01:21:18 thing
- 01:21:18 to a input element we can ignore that
- 01:21:20 form
- 01:21:22 thing for now so let's go back to
- 01:21:25 our project and to use such an input
- 01:21:28 element we need to unlock it because by
- 01:21:30 default
- 01:21:31 none of the components provided by angle
- 01:21:33 material is available in our application
- 01:21:36 and this is done to save space that our
- 01:21:38 final application is as
- 01:21:40 small as possible and we don't import
- 01:21:42 things which we don't use
- 01:21:44 now i want to use something of course so
- 01:21:47 let's
- 01:21:47 actually move that import here up to the
- 01:21:49 top to keep all the angular imports in
- 01:21:52 one place
- 01:21:53 and then let's import something from
- 01:21:56 at angular material
- 01:22:00 and that's something i want to import
- 01:22:02 here is just
- 01:22:05 a module
- 01:22:08 it's the matte input module
- 01:22:11 now we can take that module and add it
- 01:22:14 to the imports array
- 01:22:15 and what this does is it unlocks all the
- 01:22:18 input related
- 01:22:19 components so now we can go back to the
- 01:22:21 post create component html file
- 01:22:24 and there the text area we simply add
- 01:22:26 matte input to it
- 01:22:28 this is the selector which turns this
- 01:22:30 into angle material input
- 01:22:32 now let's save this and i don't see a
- 01:22:35 big difference to you
- 01:22:37 now the reason why we don't see a
- 01:22:38 difference is that actually all these
- 01:22:40 input components only work in
- 01:22:42 conjunction with another
- 01:22:44 well component we have to add as a
- 01:22:45 wrapper and that's the matte
- 01:22:48 form field component now that's just
- 01:22:51 another component provided by angular
- 01:22:52 material and we put our inputs in there
- 01:22:55 now i said we don't have to worry about
- 01:22:56 that foreign thing and we don't we won't
- 01:22:58 use a forum yet
- 01:23:00 but this is something we need to add to
- 01:23:02 get a styling that looks
- 01:23:04 better so now we can see angular
- 01:23:06 material seems to do something
- 01:23:08 we don't have that ugly input from
- 01:23:10 before now it's
- 01:23:11 also not super pretty yet but we'll get
- 01:23:14 there
- 01:23:15 to turn this into a prettier component
- 01:23:17 what i'll do is i'll use
- 01:23:19 another component from the angle
- 01:23:20 material framework and
- 01:23:22 that's the matte card
- 01:23:26 so let's add another import in the app
- 01:23:28 module matte
- 01:23:29 card module card is a special
- 01:23:32 container a look you will probably know
- 01:23:35 from
- 01:23:36 other pages let's add the matte card
- 01:23:39 module to the imports array
- 01:23:41 and then in the post create component
- 01:23:43 i'll wrap my mat form field here
- 01:23:45 with matte dash card now this creates
- 01:23:49 such a card look if i put it in there
- 01:23:51 and we save that
- 01:23:53 you will see now it's indented a bit
- 01:23:55 more and you see there's a slight shadow
- 01:23:57 below that now we can't see it that well
- 01:23:59 because a bit hard to see it's taking up
- 01:24:01 all the width so let's restrict it with
- 01:24:03 by also adding some custom styles to
- 01:24:05 that we can still do that
- 01:24:06 i'll add a new file post create
- 01:24:10 component.css for the styling for this
- 01:24:12 component
- 01:24:13 and we need to import this by going to
- 01:24:15 the typescript file of the component
- 01:24:17 and adding style urls here now that's an
- 01:24:20 array of external stylesheets
- 01:24:22 we can only have one template but we can
- 01:24:24 have multiple styles
- 01:24:25 and there a point at post create
- 01:24:28 component.css
- 01:24:30 now we can write our own css code there
- 01:24:32 and i will
- 01:24:33 target my matte card element that's cool
- 01:24:37 we can use the angular
- 01:24:38 selectors here as style targets so we'll
- 01:24:42 target
- 01:24:42 matte card here and actually
- 01:24:45 restrict the width to let's say 80
- 01:24:48 percent
- 01:24:49 and add margin auto to center this
- 01:24:52 now if we save that now we can see the
- 01:24:55 card here a bit better
- 01:24:56 and we got our form field in there and
- 01:24:59 if we type you see
- 01:25:00 dissolve form field now this is taking
- 01:25:03 shape
- 01:25:04 now i'm still not perfectly happy with
- 01:25:06 that i also want to change the look of
- 01:25:08 my text area a bit more
- 01:25:10 so also target my text area in that
- 01:25:12 component
- 01:25:13 and the cool thing is these styles will
- 01:25:16 be scoped to this component
- 01:25:18 so even if we use a text area or a matte
- 01:25:20 card in another component
- 01:25:22 these styles will not apply to it it
- 01:25:24 will just apply the styles to the
- 01:25:26 elements in this component
- 01:25:28 so i'll take my text area and set the
- 01:25:30 width of it to 100 percent here actually
- 01:25:33 however for this to have an effect i
- 01:25:35 also need to
- 01:25:36 take the wrapping element matte form
- 01:25:39 field and give that
- 01:25:40 a width of 100 and now if we save that
- 01:25:44 you see the input is spanning the entire
- 01:25:47 width here
- 01:25:49 and now i want to put my button into the
- 01:25:50 card too so i'll take that button
- 01:25:53 put it below that mat form field remove
- 01:25:56 the
- 01:25:56 hr tag here and of course it would be
- 01:25:58 nice if the button would look prettier
- 01:26:00 too
- 01:26:01 so we can turn it into a material design
- 01:26:03 button by including one more thing from
- 01:26:05 the angle material package
- 01:26:07 the matte button module here and i will
- 01:26:10 add this
- 01:26:11 down there matte button module
- 01:26:15 so now we're including the matte button
- 01:26:18 module and now we can go back to our
- 01:26:20 html code
- 01:26:21 and turn this into a nice looking button
- 01:26:23 by adding matte
- 01:26:24 button or matte raised button to get
- 01:26:27 this raised button look
- 01:26:29 and you can find out which values you
- 01:26:31 can use of course
- 01:26:33 in the angle material docs in case you
- 01:26:35 want to dive deeper
- 01:26:36 you can always dive into the docs read
- 01:26:38 through them check the api documentation
- 01:26:40 for a full list of the features you can
- 01:26:42 configure
- 01:26:43 things like that so now this is the
- 01:26:45 button now it would be nicer if it has
- 01:26:47 some color
- 01:26:48 and thankfully if you check out the docs
- 01:26:50 you find out that you can add a color
- 01:26:52 property i'm just splitting this over
- 01:26:54 multiple lines to make it easier to read
- 01:26:56 so here i will add color and you can set
- 01:26:59 this to primary
- 01:27:00 or accent or worn now word is some
- 01:27:04 warning color
- 01:27:06 red don't want to do that i want to use
- 01:27:08 my primary color
- 01:27:10 whoops primary and now this will use the
- 01:27:12 indigo color in this case because i'm
- 01:27:14 using the indigo pink
- 01:27:15 theme you can of course all use accent
- 01:27:18 and maybe i actually prefer this
- 01:27:20 i think it's even clearer to see so now
- 01:27:22 we get the button we get the input here
- 01:27:24 now this is looking prettier now it's
- 01:27:27 time to add a toolbar
- 01:27:29 and then also add a real
- 01:27:32 posts management because right now we're
- 01:27:34 not really adding new posts we're just
- 01:27:36 overwriting some text which we output
- 01:27:39 time to change that
- 01:27:48 let's start with the toolbar
- 01:27:52 because i think every application has
- 01:27:54 some sort of header
- 01:27:55 and i'll actually create a new component
- 01:27:57 for that so not on the posts folder but
- 01:28:00 in the app folder itself i'll add a new
- 01:28:01 folder
- 01:28:02 header and in there i want to create my
- 01:28:05 own header component so i'll
- 01:28:06 name it header.component.ts and add a
- 01:28:10 header.component.html file
- 01:28:12 you learned how we create these
- 01:28:13 components so go through that a
- 01:28:15 bit quicker export my class header
- 01:28:18 component in there and add the add
- 01:28:22 component decorator which you need to
- 01:28:25 import from at
- 01:28:26 angular core my ide automatically added
- 01:28:28 the import you might need to do that
- 01:28:30 manually depending on your id
- 01:28:32 add a selector i'll name it add app
- 01:28:34 header
- 01:28:36 and then also add a template
- 01:28:39 or a template url and here i'll be
- 01:28:42 pointing
- 01:28:42 to my header.component.html file
- 01:28:47 now that's the header component
- 01:28:48 typescript file in the html file i will
- 01:28:51 use yet another component provided by
- 01:28:53 the angle material
- 01:28:54 framework so in app module we need to
- 01:28:57 unlock that first
- 01:28:58 here to our import list from add angular
- 01:29:01 material i'll import yet another module
- 01:29:04 the matte toolbar module now as you
- 01:29:07 probably can guess this unlocks a
- 01:29:09 certain toolbar component
- 01:29:12 to unlock it for angular we need to add
- 01:29:14 this to our
- 01:29:16 imports array and now we can use the
- 01:29:19 material design toolbar
- 01:29:21 let's quickly check out the docs there
- 01:29:23 on the left you find
- 01:29:24 toolbar and you can check out the demo
- 01:29:27 code as you can see it's really easy to
- 01:29:28 use not that difficult
- 01:29:30 you can configure a lot though again
- 01:29:32 feel free to read through the entire
- 01:29:34 documentation here
- 01:29:35 so i will add it in my header component
- 01:29:38 toolbar
- 01:29:39 and we can for example set a color which
- 01:29:41 i will set to primary because i don't
- 01:29:43 like that
- 01:29:44 boring grayish look and
- 01:29:47 there for now i'll just set
- 01:29:50 my messages as a title so to say
- 01:29:54 now the header component isn't used yet
- 01:29:56 to use it we first of all need to unlock
- 01:29:58 it so we go to
- 01:29:59 declarations in our app module not
- 01:30:02 imports because we're not importing
- 01:30:03 another module we're just importing
- 01:30:05 another
- 01:30:06 component in our case and there i will
- 01:30:08 add
- 01:30:09 my own component so i'll again let my
- 01:30:13 ide automatically import this and i will
- 01:30:14 just add
- 01:30:15 header component and my ide adds the
- 01:30:19 import up here
- 01:30:20 this is important so now this is added
- 01:30:23 now we can
- 01:30:23 use the header component here
- 01:30:27 and i want to use it in my app component
- 01:30:29 instead of our first app
- 01:30:31 i'll add app header like
- 01:30:34 this now with that added here
- 01:30:37 let's save this let's go back to our
- 01:30:39 application and we get this nice toolbar
- 01:30:42 above the rest of our application now
- 01:30:44 the card is sitting directly on the edge
- 01:30:46 of the toolbar
- 01:30:48 to change this what we can do is we can
- 01:30:51 simply wrap our
- 01:30:54 main content with the main element now
- 01:30:56 that's a normal html element
- 01:30:59 put our post create component in there
- 01:31:01 and now
- 01:31:02 style that main element directly here
- 01:31:04 the app component css file maybe
- 01:31:06 and you can of course also use css class
- 01:31:09 selectors you don't have to always
- 01:31:10 select the elements
- 01:31:12 so here i will give this some margin to
- 01:31:14 the top
- 01:31:15 of let's say one rem or
- 01:31:18 16 pixels would be the equivalent uh
- 01:31:20 whichever unit you prefer
- 01:31:22 i will work with rams here so now we get
- 01:31:24 some distance between the card and the
- 01:31:26 toolbar
- 01:31:27 now the thing that is missing for now
- 01:31:29 we'll add navigation later
- 01:31:31 the thing that is missing for now is a
- 01:31:33 way to output the posts it would be nice
- 01:31:35 to output the posts
- 01:31:37 below our input area here so let's do
- 01:31:40 this
- 01:31:42 next
- 01:31:50 so the goal is to be able to output the
- 01:31:52 posts and for this i'll add another new
- 01:31:54 component
- 01:31:55 because i said you want to be granular
- 01:31:57 and creating a post
- 01:31:59 is actually something which is decoupled
- 01:32:01 from outputting the posts
- 01:32:03 so in the post folder i'll create a new
- 01:32:05 subfolder
- 01:32:06 which i'll name post list and in there
- 01:32:08 i'll add my
- 01:32:10 post dash com file
- 01:32:13 and the post list.component.html file
- 01:32:16 for the html content
- 01:32:19 now you know how to create such a
- 01:32:20 component by the way if you use the cli
- 01:32:22 regularly for that
- 01:32:24 you can also create components with the
- 01:32:25 cli with a command
- 01:32:27 i'm a fan of the manual approach also
- 01:32:29 because it's really good for practicing
- 01:32:31 so here i'll export another class post
- 01:32:33 list
- 01:32:35 component and as you know we add the add
- 01:32:39 component
- 01:32:41 decorator to it and in there we add a
- 01:32:43 selector
- 01:32:44 this will be app post list
- 01:32:48 and a template url link where we
- 01:32:51 point to our post list component
- 01:32:56 dot html file so now we got that base
- 01:33:00 component set up
- 01:33:01 as you know we need to include it to app
- 01:33:02 module to use it
- 01:33:04 so in the declarations array i'll add my
- 01:33:06 post list
- 01:33:07 component also add the import here my
- 01:33:10 ide added it
- 01:33:11 and with that we can use it in the app
- 01:33:14 component
- 01:33:14 maybe below the app post create
- 01:33:17 component
- 01:33:18 there we could add app post list
- 01:33:21 like this now right now our component is
- 01:33:24 empty
- 01:33:25 the goal is to render a list of posts in
- 01:33:28 there
- 01:33:28 so for now first of all let's go back to
- 01:33:30 post create component and get rid of
- 01:33:32 that ugly paragraph
- 01:33:33 and then dive into the post list
- 01:33:35 component html template
- 01:33:37 i want to use another feature of the
- 01:33:39 angle material package
- 01:33:41 and that can be found under layout i
- 01:33:43 want to use the expansion panel
- 01:33:45 which is a collapsible well panel where
- 01:33:48 we can display some content
- 01:33:50 now to use this i'll go back to the app
- 01:33:54 module
- 01:33:55 and import one additional module from
- 01:33:57 angular material
- 01:33:59 the matte expansion module
- 01:34:03 and also add this to the imports array
- 01:34:05 here mat
- 01:34:06 expansion module like this and now with
- 01:34:10 that added
- 01:34:11 let's go back to the post list component
- 01:34:13 html file
- 01:34:14 and to use it we can again have a look
- 01:34:17 at the official docs
- 01:34:18 at the dummy source code there as you
- 01:34:21 can see
- 01:34:21 they use the matte accordion to wrap
- 01:34:23 this all this is used to basically be
- 01:34:25 able to orchestrate all these expansion
- 01:34:28 panels
- 01:34:28 now we can easily recreate this by
- 01:34:32 adding matte accordion here
- 01:34:36 as an element in our post list component
- 01:34:38 html file
- 01:34:40 and in there add the matte expansion
- 01:34:43 panel
- 01:34:44 element and in that matte expansion
- 01:34:47 panel element
- 01:34:48 you can have a matte expansion panel
- 01:34:50 header
- 01:34:51 this allows you to define a title
- 01:34:54 and below that header you can also have
- 01:34:57 some regular
- 01:34:58 content like here i'm in
- 01:35:03 an expansion panel like this
- 01:35:07 and this would be the expansion
- 01:35:11 title now if we save that and we go back
- 01:35:14 to our application
- 01:35:17 we can see our expoundable element here
- 01:35:20 now it's sitting directly beneath the
- 01:35:22 card at the top here
- 01:35:24 which is not super pretty additionally
- 01:35:26 i'd also like to restrict the width of
- 01:35:28 that
- 01:35:29 since i want to do restrict the width of
- 01:35:31 both the input and this
- 01:35:33 maybe i want to restrict the width of
- 01:35:34 the total main content
- 01:35:36 so let's go actually to the post create
- 01:35:39 component
- 01:35:40 to the style there and i will not set
- 01:35:44 matte card here anymore to have a width
- 01:35:46 of 80 percent
- 01:35:47 instead i go to my app component css
- 01:35:50 file
- 01:35:51 and for the main area here there
- 01:35:54 i will set a width of 80 percent
- 01:35:58 and margin auto for now so now
- 01:36:02 both is limited in width and centered
- 01:36:04 now to have some spacing between
- 01:36:06 our post list component and our post
- 01:36:09 create component
- 01:36:10 we get multiple ways of achieving this
- 01:36:12 one simple way is
- 01:36:13 to add a margin top to our post list
- 01:36:16 component
- 01:36:17 and we can do this by adding post list
- 01:36:19 component
- 01:36:20 dot css here and import
- 01:36:24 this into our post list component by
- 01:36:27 adding style urls here
- 01:36:29 post list component dot css
- 01:36:33 and in here then target a special
- 01:36:35 selector
- 01:36:36 the host selector which targets the
- 01:36:39 element itself so to say
- 01:36:41 and add a margin top of one
- 01:36:44 ram and if we save that
- 01:36:48 nothing changed because actually all the
- 01:36:50 elements by default
- 01:36:51 are not treated as block level elements
- 01:36:53 so we have to set
- 01:36:55 display to block first once we do that
- 01:36:58 now we get some spacing here cool so now
- 01:37:00 this is working
- 01:37:01 now let's go back to populating this
- 01:37:03 with some content too
- 01:37:05 we get a title and our well content so
- 01:37:08 we might want to add a new field for a
- 01:37:11 title here eventually
- 01:37:13 but first of all let's see how we could
- 01:37:15 output a list of some dummy posts
- 01:37:18 so back in the post list component we
- 01:37:20 only got
- 01:37:21 one expansion panel with hard-coded
- 01:37:23 content in there
- 01:37:24 now let's say we had a list of posts so
- 01:37:27 the post list component let's say we
- 01:37:29 have
- 01:37:29 posts and this actually is an array
- 01:37:33 and in there we got some javascript
- 01:37:35 object where every post has
- 01:37:37 a title like first post and some content
- 01:37:41 like this is the first post
- 01:37:47 content and we had not just one
- 01:37:50 but three posts so the second and
- 01:37:54 the third post and here we got the
- 01:37:56 second posts and
- 01:37:57 the third post content now would be nice
- 01:38:00 if we could
- 01:38:01 dynamically loop through all these posts
- 01:38:03 and output that data in our template
- 01:38:05 right
- 01:38:06 now actually angular has us covered when
- 01:38:09 it comes to this
- 01:38:10 it offers so-called directives which i
- 01:38:13 already mentioned before briefly which
- 01:38:15 allow us to manipulate elements
- 01:38:17 in the dom when needed now let's dive
- 01:38:20 deeper into what i mean with this and
- 01:38:22 how this works
- 01:38:23 in the next lecture
- 01:38:32 the last lecture we added our expansion
- 01:38:34 panels and now we get
- 01:38:36 some data here and that's a typical use
- 01:38:38 case right it is also what we will have
- 01:38:40 at the end of this course
- 01:38:41 you fetch data from some backend from
- 01:38:44 some server
- 01:38:44 a list of posts a list of users whatever
- 01:38:47 it is and you want to output this in
- 01:38:49 your template
- 01:38:50 therefore you don't know in advance how
- 01:38:52 many elements you're going to need
- 01:38:54 we only got one expansion panel now we
- 01:38:56 would need three
- 01:38:57 and we don't want to hard code our
- 01:38:58 content in there anyways
- 01:39:00 so we need some way of dynamically
- 01:39:02 looping through that code
- 01:39:03 and creating as many panels as required
- 01:39:07 and we can do that with the help of a
- 01:39:08 so-called structural directive
- 01:39:11 angular ships with directives which as i
- 01:39:13 mentioned before
- 01:39:14 are instructions you place on an element
- 01:39:16 and there are some instructions that
- 01:39:18 only apply to a single element
- 01:39:20 ng-model was one of them but there also
- 01:39:23 are instructions
- 01:39:24 which structurally change the rendered
- 01:39:26 html code
- 01:39:27 and that's the case here we can use
- 01:39:30 another special directive
- 01:39:32 ng4 and you add with star and g4
- 01:39:36 the casing and the star is important
- 01:39:39 and this is essentially a helper tool
- 01:39:42 that allows you to repeat an element as
- 01:39:44 often as required
- 01:39:45 now the as often as required part is
- 01:39:48 defined here
- 01:39:49 between the quotation marks after the
- 01:39:51 equal sign
- 01:39:52 here you write the looping logic like
- 01:39:55 this
- 01:39:55 you add let to create a variable let
- 01:39:59 post in our case this name is totally up
- 01:40:01 to you
- 01:40:03 off and then the data you want to loop
- 01:40:05 through so here
- 01:40:06 it's this post's name so this is now not
- 01:40:10 up to you or
- 01:40:10 it's up to you but you have to change it
- 01:40:12 here and in the component if you change
- 01:40:14 it
- 01:40:14 and now we're looping through all the
- 01:40:16 posts and we're storing the individual
- 01:40:18 post
- 01:40:18 in this post variable which is created
- 01:40:21 here
- 01:40:22 and now the cool thing is we can use
- 01:40:24 that variable in the template
- 01:40:25 here we can output post title here for
- 01:40:29 example
- 01:40:30 and down there we can output composed
- 01:40:33 content like that and now it will create
- 01:40:36 as many expansion panels as we need and
- 01:40:38 give us access
- 01:40:40 to the data we're looking at and now if
- 01:40:42 we save this
- 01:40:43 we get three expansion panels for the
- 01:40:46 different posts
- 01:40:47 and you see by default only one of them
- 01:40:49 can be opened if you want to allow
- 01:40:50 multiple ones
- 01:40:51 you can add multi and set this to true
- 01:40:55 on the accordion now you would also be
- 01:40:58 able
- 01:40:58 to expand more than one post at a time
- 01:41:02 so this is now our accordion with the
- 01:41:05 posts
- 01:41:05 and this is how we can render data a
- 01:41:08 list of data dynamically
- 01:41:10 with the help of ng4
- 01:41:13 now of course we don't want to use
- 01:41:15 hard-coded data we want to use
- 01:41:17 data which we actually receive from
- 01:41:21 well the post create component in our
- 01:41:23 case here
- 01:41:25 and to do that i'll get rid of my dummy
- 01:41:28 data here i'll actually comment it out
- 01:41:30 so that we still have it for reference
- 01:41:33 but i'll set post to an empty array now
- 01:41:36 and this is an empty array and if it is
- 01:41:38 empty
- 01:41:39 well then we actually don't render
- 01:41:40 anything maybe we want to show a
- 01:41:43 placeholder
- 01:41:44 and we can use another structural
- 01:41:45 directive for that
- 01:41:47 so back in the html template we could
- 01:41:50 say
- 01:41:51 we only want to render this accordion
- 01:41:53 here with all these posts
- 01:41:55 if we got posts so what i can do is i
- 01:41:58 can check
- 01:41:58 with another structural directive which
- 01:42:00 with ng if
- 01:42:02 if a certain condition is true and only
- 01:42:04 if it is true
- 01:42:05 only then this part on which ngf sets
- 01:42:08 and
- 01:42:09 all the child components will be
- 01:42:11 rendered and that's important it's not
- 01:42:12 hidden if it's not true
- 01:42:14 it's not part of the dom it will only be
- 01:42:16 added to the dom
- 01:42:17 if this condition is true and what is
- 01:42:19 the condition
- 01:42:20 anything you want so you can refer to a
- 01:42:23 function here which returns true or
- 01:42:25 false
- 01:42:25 to a property that stores true or false
- 01:42:28 or
- 01:42:28 write a short code snippet here i'll
- 01:42:31 check if post's
- 01:42:32 length is greater than zero and if it's
- 01:42:35 not
- 01:42:36 then this will not be rendered in that
- 01:42:39 case i want to render something else
- 01:42:41 i want to render a paragraph where i say
- 01:42:44 no posts added yet
- 01:42:48 lowercase p and i will add ng if to that
- 01:42:52 2
- 01:42:52 and here i will check if posts length is
- 01:42:56 smaller or equal to zero then i will
- 01:42:58 render this
- 01:42:59 fallback text this is why we see no
- 01:43:01 posts added yet here
- 01:43:03 now this clearly looks super ugly
- 01:43:05 thankfully we can change this with some
- 01:43:07 built-in css classes
- 01:43:09 you can find more under guides and
- 01:43:12 they're
- 01:43:13 using angle materials typography here
- 01:43:15 are some classes you can add
- 01:43:17 and there i will add body one as a class
- 01:43:21 here matt that's always appended at the
- 01:43:25 edit at the beginning matte dash body
- 01:43:28 one and now if we save that we got a
- 01:43:30 nicer look
- 01:43:31 now it has the roboto font for example
- 01:43:34 and if we want to center this for
- 01:43:35 example
- 01:43:36 well then we can also add another class
- 01:43:40 because i don't want to style all
- 01:43:41 paragraphs i just want to style this
- 01:43:43 paragraph
- 01:43:44 so this will be my info text
- 01:43:48 and i will target this now in my css
- 01:43:51 file
- 01:43:51 info text and simply set text align here
- 01:43:55 to center and now we're using some
- 01:43:58 structural directives
- 01:43:59 to present a nice user interface time to
- 01:44:02 be able to finally add
- 01:44:04 some posts and connect the post create
- 01:44:06 component with the post
- 01:44:08 list component
- 01:44:17 so would be nice if we could add posts
- 01:44:19 right
- 01:44:20 and to be able to do so we first of all
- 01:44:23 need to add one more input field
- 01:44:25 to our um well post create component
- 01:44:28 right now we only got the text area i
- 01:44:31 will actually add
- 01:44:32 one additional one mat form field here
- 01:44:36 and in there i'll add a normal input for
- 01:44:38 the title
- 01:44:39 now important to turn this into a
- 01:44:41 material input field we have to add
- 01:44:43 matte
- 01:44:44 input and this now well as i said
- 01:44:48 should give me the title i want to add
- 01:44:50 so here i will for now also use two-way
- 01:44:53 binding i'll rename this to entered
- 01:44:56 content and i will have the entered
- 01:45:00 title queue we can also get rid of
- 01:45:05 new post also down there
- 01:45:08 maybe swap position steer to have the
- 01:45:10 title first
- 01:45:12 go back to the template and use entered
- 01:45:15 content here and on the first input use
- 01:45:18 ngmodel and two-way binding
- 01:45:22 to bind this to the entered title so now
- 01:45:25 this is all
- 01:45:26 up to date now we can create a new post
- 01:45:29 in on add post
- 01:45:31 store in a constant because we're not
- 01:45:33 changing it
- 01:45:34 new javascript object where we have a
- 01:45:36 title property
- 01:45:37 and where we store the entered title and
- 01:45:40 where we have the content property
- 01:45:43 to store the entered content and we can
- 01:45:46 also structure this over multiple lines
- 01:45:48 to make the bit easier
- 01:45:50 to read i guess now the thing is
- 01:45:54 this post is here that's cool how do we
- 01:45:57 get it into the other component
- 01:45:59 we can use this property and event
- 01:46:02 binding thing you learned about
- 01:46:04 with the click listener and so on we can
- 01:46:06 use that on our own components too
- 01:46:08 we can emit our own events and we can
- 01:46:11 also
- 01:46:11 send data into a component and we want
- 01:46:14 to emit an event here in post create we
- 01:46:16 want to emit and
- 01:46:17 hey i got a new post event and we want
- 01:46:20 to listen to that event in the app
- 01:46:21 component which is where we were using
- 01:46:23 the post create
- 01:46:24 we then want to get the created post
- 01:46:28 add it to a posts array which we
- 01:46:31 probably managed in the app component
- 01:46:32 then later
- 01:46:33 and pass that post array down to app
- 01:46:36 post list
- 01:46:37 so step by step let's first of all
- 01:46:41 go to the post create component and emit
- 01:46:44 our own event
- 01:46:46 to emit an own event we need a feature
- 01:46:48 provided by angular core
- 01:46:49 the event emitter then we add a new
- 01:46:52 property
- 01:46:53 and that property here can have any name
- 01:46:56 you want
- 01:46:57 so i'll name it post created it makes
- 01:47:01 sense to kind of use your event name
- 01:47:03 as a property name here and that will be
- 01:47:05 a new event
- 01:47:07 emitter created with the new keyword
- 01:47:10 and now with that we can go to on add
- 01:47:13 post
- 01:47:14 and call this post created and then
- 01:47:17 emit to emit a new event now here we
- 01:47:20 wanna pass
- 01:47:21 our post as an argument that's important
- 01:47:25 so this passes the post as an argument
- 01:47:29 cool so how can we listen to that well
- 01:47:32 we first of all have to make angular
- 01:47:34 aware
- 01:47:34 that post created is an event to which
- 01:47:37 you can listen from the outside
- 01:47:39 whilst it makes sense to be able to do
- 01:47:41 that because you really want to listen
- 01:47:42 to events you emit
- 01:47:43 in the same component you still have to
- 01:47:46 do this explicitly
- 01:47:48 and you do this by adding a decorator to
- 01:47:50 this property
- 01:47:51 this decorator is called output
- 01:47:55 so just like you added add component to
- 01:47:57 the class here
- 01:47:58 you now add add output and don't forget
- 01:48:02 the parentheses
- 01:48:03 to post created this turns this into an
- 01:48:06 event which you can listen to
- 01:48:07 from the outside and from the outside
- 01:48:10 means
- 01:48:10 in the parent component so in the
- 01:48:12 component where you're using
- 01:48:14 the selector there we can now use
- 01:48:18 event binding to listen to post created
- 01:48:22 and then again execute any code we want
- 01:48:24 whenever this event occurs
- 01:48:27 and of course what i want to do here is
- 01:48:28 i want to get that post
- 01:48:30 and store it in a list of posts so in
- 01:48:32 the app component here
- 01:48:33 i'll overwrite title here with a new
- 01:48:36 posts property which is an empty array
- 01:48:38 initially
- 01:48:39 but then here i'll add onpost edit
- 01:48:43 as a method as a function so to say and
- 01:48:46 we know that we will get a post as an
- 01:48:49 argument here
- 01:48:50 and it will therefore set this post or
- 01:48:53 call this post
- 01:48:54 and call push here and push this new
- 01:48:57 post
- 01:48:57 on this list to store it there
- 01:49:00 now that's one part now we're adding
- 01:49:03 this post here
- 01:49:04 of course this doesn't do that much we
- 01:49:06 also need to be able
- 01:49:08 to pass this post down or first of all
- 01:49:10 let's connect
- 01:49:11 post created with on post added so
- 01:49:15 the method name you chose here and to
- 01:49:18 pass on the data you're getting you have
- 01:49:20 to use a special variable name
- 01:49:22 and that is dollar sign event this
- 01:49:24 essentially gives you access
- 01:49:25 to the data you emitted and that's not
- 01:49:28 just for custom events that would be the
- 01:49:30 same for click events or any built-in
- 01:49:32 events too
- 01:49:33 there you also get a default dom event
- 01:49:35 object
- 01:49:36 whatever you're passing or receiving
- 01:49:38 with an event
- 01:49:39 you get access with the special dollar
- 01:49:41 sign event variable
- 01:49:43 so that you can pass it on to your own
- 01:49:45 method or use it in an inline code
- 01:49:47 statement you might have here
- 01:49:49 so now we're passing this on now we need
- 01:49:52 to pass it down to app post list
- 01:49:54 and there we can dive in we got our
- 01:49:57 posts
- 01:49:58 all we have to do is make the posts
- 01:50:01 property
- 01:50:02 bindable from outside wire property
- 01:50:05 binding
- 01:50:05 by default it's not bindable but we can
- 01:50:08 make it bindable by adding
- 01:50:10 a decorator to it and since we had at
- 01:50:12 output
- 01:50:13 for emitting an event it probably makes
- 01:50:15 sense that here
- 01:50:16 we use input and this is added with the
- 01:50:19 add sign
- 01:50:20 and then the name of the decorator input
- 01:50:22 and don't forget the parentheses
- 01:50:24 now you can bind to posts from the
- 01:50:27 outside
- 01:50:28 and from the outside again means from
- 01:50:30 the parent component
- 01:50:32 only from there only from the direct
- 01:50:34 parent
- 01:50:35 so here we add square brackets for
- 01:50:38 property binding
- 01:50:39 posts and we can set this equal to
- 01:50:43 posts here now to avoid confusion about
- 01:50:46 the names i'll actually rename this here
- 01:50:48 i'll name this stored posts
- 01:50:52 so stored post is the new name and i
- 01:50:54 will pass this on
- 01:50:55 here and now the chain is as following
- 01:50:58 we're listening to the post created
- 01:51:00 event we're adding the post
- 01:51:02 in on post added to our stored posts
- 01:51:05 list
- 01:51:06 and we're passing down that list that
- 01:51:08 array to app
- 01:51:09 post list and angular's change detection
- 01:51:12 will automatically detect whenever a new
- 01:51:14 post is created when that changes
- 01:51:16 and when it needs to render this new
- 01:51:18 post so with this we should have a
- 01:51:20 complete
- 01:51:21 chain in place that actually allows us
- 01:51:25 to enter a title here and
- 01:51:28 some content here click save post
- 01:51:32 and see that being added here and of
- 01:51:34 course
- 01:51:35 we can add another title and even more
- 01:51:38 content and continue creating
- 01:51:41 new posts so that's pretty amazing this
- 01:51:44 is how we can
- 01:51:44 create our posts here and how we can add
- 01:51:47 them with the help of property and event
- 01:51:49 binding
- 01:51:50 on our own components
- 01:52:00 we get that working chain where we add
- 01:52:03 new posts and output it here
- 01:52:04 now it's time to make our first little
- 01:52:06 optimization
- 01:52:08 as you might have seen we are using
- 01:52:11 posts in different places
- 01:52:12 we got our list of stored posts here in
- 01:52:15 the app component
- 01:52:16 we're outputting posts obviously in the
- 01:52:18 post list component and we're creating
- 01:52:20 posts here
- 01:52:21 now we ensure that they always have the
- 01:52:23 same structure title content
- 01:52:25 we do this when we create them and we
- 01:52:28 rely on this structure when outputting
- 01:52:30 them
- 01:52:30 we're referring to post title post
- 01:52:32 content so a mistake in the creation
- 01:52:34 would not be that good
- 01:52:35 additionally here in the app component
- 01:52:37 we actually just say
- 01:52:39 we have an array we could store anything
- 01:52:41 in here we could store
- 01:52:42 numbers in here and of course we are
- 01:52:44 writing our application we
- 01:52:46 probably don't mess up on purpose but if
- 01:52:48 we're working in a team or if we're
- 01:52:50 coming back to that application after
- 01:52:52 some weeks or months
- 01:52:54 we might have a hard time figuring out
- 01:52:56 immediately which kind of data we stored
- 01:52:58 there
- 01:52:58 was it post dot content or post dot
- 01:53:02 description
- 01:53:03 so it makes sense to create some models
- 01:53:06 so basically blueprints contracts which
- 01:53:08 define
- 01:53:09 how a post looks like in our angular
- 01:53:12 application
- 01:53:14 and i'll do that in my posts folder i'll
- 01:53:16 add a new file in there not a folder
- 01:53:18 just a file
- 01:53:19 and i'll name this post.model.ts
- 01:53:22 so it's a typescript file and in there
- 01:53:24 i'll use another typescript feature
- 01:53:26 a so-called interface an interface is
- 01:53:29 like a class that defines how our object
- 01:53:32 looks like but it can't be instantiated
- 01:53:35 it's more like a contract
- 01:53:37 we can use it to create our own type to
- 01:53:39 force a certain object to look like this
- 01:53:42 even though we can't directly create it
- 01:53:43 based on the interface
- 01:53:45 and here i'll name this post now
- 01:53:49 we create it like that and in there what
- 01:53:51 we can do is
- 01:53:52 we can now define the fields and methods
- 01:53:55 this should have
- 01:53:57 and i want to have a field title which
- 01:54:00 should be of type string
- 01:54:01 assigned with a colon and i want to have
- 01:54:04 another field content which should also
- 01:54:06 be a string
- 01:54:07 and this ensures that we got a clear
- 01:54:09 definition of how a post looks like
- 01:54:11 in our application now of course an
- 01:54:14 interface in this file isn't that useful
- 01:54:16 so i add export to make it available
- 01:54:18 outside of this file too
- 01:54:20 and now we can import this in all the
- 01:54:22 files where we're using this
- 01:54:24 so in the app component for example we
- 01:54:26 can now add an
- 01:54:27 import import post
- 01:54:30 from and then simply go to posts and
- 01:54:34 import it from that post
- 01:54:35 model file without the extension as
- 01:54:37 always and now we can say that stored
- 01:54:40 posts
- 01:54:40 is an array of posts by adding a colon
- 01:54:43 here
- 01:54:44 and then post square brackets this is
- 01:54:46 typescript syntax for saying
- 01:54:48 we got an array of posts in there and
- 01:54:50 now if we would try to add a free
- 01:54:53 we actually get an error that a free is
- 01:54:56 not a post
- 01:54:57 so this is pretty cool we get a warning
- 01:54:59 here we would also get a warning if we
- 01:55:00 try to save this and compile this
- 01:55:02 of course we got other places where we
- 01:55:04 use the post too in the post
- 01:55:06 list here we got another list of posts
- 01:55:09 so here it's the same thing
- 01:55:11 we import post from go up one level
- 01:55:15 post model and then assign a type here
- 01:55:18 and say we got a list of posts
- 01:55:21 and finally in the post create component
- 01:55:24 there too i want to import
- 01:55:28 my posts type so to say
- 01:55:31 from post model post
- 01:55:36 model like this and then whenever we
- 01:55:39 create a new post
- 01:55:41 this will actually be of type post
- 01:55:45 we can be very clear about this and we
- 01:55:47 can even be clear
- 01:55:48 about the data we're going to emit event
- 01:55:51 emitter is a so-called
- 01:55:52 generic type which simply means we can
- 01:55:55 pass additional
- 01:55:56 information about which type of data it
- 01:56:00 works with and the event emitter
- 01:56:02 works with data in the sense of it emits
- 01:56:05 data
- 01:56:06 and that data will be opposed so we can
- 01:56:08 add lower than greater than signs that
- 01:56:11 is how you define such a generic type
- 01:56:13 post
- 01:56:15 now we're saying data we emit will be a
- 01:56:18 post
- 01:56:18 and now we're pretty safe because now if
- 01:56:21 we ever try to
- 01:56:22 emit different data or do something else
- 01:56:25 we would get an error
- 01:56:26 and therefore now we can come back to
- 01:56:29 that code and quickly see
- 01:56:30 how a post looks like
- 01:56:40 it's all the time for one hour
- 01:56:42 improvement when creating posts right
- 01:56:44 now we're doing this with two-way
- 01:56:45 binding
- 01:56:46 and it's not necessarily wrong but
- 01:56:48 angular also makes it easy to work with
- 01:56:50 forms
- 01:56:51 and of course it makes sense to all the
- 01:56:53 user forms semantically
- 01:56:55 so what we can do is we can add a form
- 01:56:57 element normal html
- 01:56:58 element in our card here in the
- 01:57:01 postgreat component
- 01:57:02 and wrap the form fields and the button
- 01:57:05 with it
- 01:57:05 like this and unfortunately it removed
- 01:57:09 my
- 01:57:10 multi-line setup here let me recreate
- 01:57:12 that
- 01:57:13 and now in here i got my different
- 01:57:16 inputs
- 01:57:17 in that form and now we don't need to
- 01:57:20 use two-way binding anymore though we
- 01:57:22 can
- 01:57:22 we can use another mechanism angular
- 01:57:25 provides
- 01:57:27 when it detects a form element and we
- 01:57:30 get the
- 01:57:30 forms module included which we do
- 01:57:34 it will automatically create a
- 01:57:35 javascript object behind the scenes
- 01:57:38 which represents this form so to say
- 01:57:41 where we can easily register inputs as
- 01:57:44 controls of which it will keep track of
- 01:57:46 where it will then store the values of
- 01:57:48 these controls and where we can easily
- 01:57:50 add validation to
- 01:57:52 and submit the form and use the value of
- 01:57:54 that form
- 01:57:56 for that we can get rid of the two-way
- 01:57:58 binding here with this syntax
- 01:58:00 and instead add ng-model like this so as
- 01:58:02 a directive without any bindings
- 01:58:05 this will register this input as a
- 01:58:07 control
- 01:58:08 to this behind the scenes form however
- 01:58:11 angular needs to know how to name this
- 01:58:13 input so we need to add the normal name
- 01:58:16 attribute and give this any name of your
- 01:58:18 choice i'll name it title and the same
- 01:58:21 for the text area we can use
- 01:58:23 ng model we need to add a name now so i
- 01:58:26 will name this
- 01:58:28 content maybe all the reduce to rows but
- 01:58:31 that of course is optional
- 01:58:32 and now angular is aware of these two
- 01:58:34 controls on this form
- 01:58:36 now when we click the button i don't
- 01:58:39 want to call
- 01:58:40 on add post manually anymore instead
- 01:58:43 i will set this button to be of type
- 01:58:45 submit because we're now in a forum and
- 01:58:47 the default html behavior is that a
- 01:58:49 button with type submit
- 01:58:51 in a form will submit that form and
- 01:58:54 submitting will trigger a special event
- 01:58:56 to which we can listen to
- 01:58:57 the submit event and that is where i
- 01:58:59 want to
- 01:59:01 execute on add post like this
- 01:59:05 now on it post remember is our method
- 01:59:07 here
- 01:59:08 so now we're doing this whenever we're
- 01:59:10 submitting the form and angular will
- 01:59:12 also prevent the default
- 01:59:14 which would be that the form gets sent
- 01:59:16 to the server we don't want to do that
- 01:59:18 we want to handle this entirely in
- 01:59:19 javascript
- 01:59:21 now with that we get the form here now
- 01:59:24 we need to get access to the values
- 01:59:26 inside of that form
- 01:59:28 and this can be done with the help of a
- 01:59:29 local reference
- 01:59:31 we can add a reference to the forum and
- 01:59:34 you can name this however you want
- 01:59:35 like post form and now important you
- 01:59:38 don't just add it like this
- 01:59:39 this would give us access to the html
- 01:59:41 element object
- 01:59:43 we can actually assign a value here and
- 01:59:45 that value
- 01:59:46 has to be ng form now that is a
- 01:59:49 directive
- 01:59:50 angular implicitly attaches to the form
- 01:59:52 element here for us
- 01:59:54 and what this strange syntax does is it
- 01:59:57 gives us access to this
- 01:59:59 object this form object angular created
- 02:00:02 for us and manages for us
- 02:00:04 behind the scenes so now post form gives
- 02:00:07 us access to that
- 02:00:08 angular form object and we can pass post
- 02:00:11 form as an argument to on add post
- 02:00:14 and then on add post we now know that we
- 02:00:16 received the form
- 02:00:17 which actually is of type ng forum which
- 02:00:20 you
- 02:00:20 automatically or what you import my ide
- 02:00:23 does it automatically
- 02:00:24 from at angular forms so at angular
- 02:00:27 forms this gives us access to ng form
- 02:00:31 and this now actually holds a lot of
- 02:00:34 information about the form
- 02:00:35 for example whether it's valid or not
- 02:00:38 but it also gives us access to the
- 02:00:40 values of the form on the forum there is
- 02:00:42 a value property
- 02:00:44 and on that value property we can access
- 02:00:46 things like
- 02:00:47 title so essentially the names we
- 02:00:50 defined here
- 02:00:51 title and content so foreign value title
- 02:00:55 gives us the title the user entered
- 02:00:57 forum value content gives us the content
- 02:01:00 obviously now it's possible to enter
- 02:01:02 invalid content
- 02:01:03 we can submit an empty form and we add
- 02:01:06 an empty post therefore
- 02:01:08 clearly not what we want we can easily
- 02:01:11 add validation
- 02:01:12 by adding some default html5 validators
- 02:01:16 to our inputs so this is not angular
- 02:01:19 there is a required validator for
- 02:01:21 example now what angular will do though
- 02:01:23 is
- 02:01:23 it will automatically detect this and
- 02:01:26 then run some behind-the-scenes logic
- 02:01:27 and javascript
- 02:01:28 to also update its form object
- 02:01:32 to reflect whether it's valid or not so
- 02:01:34 if it fulfills our
- 02:01:35 html5 validators so i will require both
- 02:01:39 you could add more for example there
- 02:01:41 also is a min
- 02:01:43 length validator where you could say the
- 02:01:45 minimum length of a title is free
- 02:01:48 and not just one as it is with required
- 02:01:50 these are things you can add
- 02:01:52 now we got the validators in place and
- 02:01:54 now angular is aware of the fact whether
- 02:01:56 the form is valid or not
- 02:01:58 that being said whilst this is the case
- 02:02:01 we can still submit an invalid form
- 02:02:04 if i hit save post you see it actually
- 02:02:07 marks them as
- 02:02:08 invalid by underlining them in red
- 02:02:10 that's the angular material feature
- 02:02:12 but it still submits it if we want to
- 02:02:15 prevent
- 02:02:15 that we have to do it manually in on add
- 02:02:19 post we can check if
- 02:02:20 forum invalid and if this is true
- 02:02:25 then we just return what this means is
- 02:02:28 that now if i reload and click the
- 02:02:30 button no post is added
- 02:02:32 but it still tried to submit it but now
- 02:02:34 it marks it as red
- 02:02:36 and now thanks to angular material we
- 02:02:37 can also easily add
- 02:02:39 beautiful error messages if we go back
- 02:02:42 to angle material
- 02:02:43 and there to the form field there
- 02:02:48 on the right you can click on error
- 02:02:49 messages
- 02:02:51 and you see there's a special matte
- 02:02:53 error component you can add below the
- 02:02:55 input
- 02:02:56 let's copy that into our post create
- 02:02:58 component input here
- 02:03:00 so below the input i add this and we
- 02:03:02 don't want to check email here there we
- 02:03:04 want to get access to that input
- 02:03:05 more on that in a second but we can
- 02:03:07 check whether this is invalid
- 02:03:09 and then well display an error message
- 02:03:12 we'll also have to change that
- 02:03:14 so what we can do here is first of all
- 02:03:15 we need to get access to that input
- 02:03:17 and there are two ways of doing so we
- 02:03:19 can reach out to our post form
- 02:03:21 and there call get control then pass the
- 02:03:24 name between
- 02:03:25 quotation marks and get access to the
- 02:03:28 control like this
- 02:03:29 or we add a local reference to that
- 02:03:31 input any name you want
- 02:03:32 like title and set this equal to ng
- 02:03:35 model
- 02:03:36 so where ng forum gave you access to the
- 02:03:38 entire form this gives you access to the
- 02:03:40 well data managed for that input behind
- 02:03:43 the scenes
- 02:03:43 and then you could also say title
- 02:03:46 invalid because now this
- 02:03:47 is the form control behind the scenes
- 02:03:50 now whatever you want to output here
- 02:03:51 can be dynamic content but it can also
- 02:03:53 be some hard-coded text like
- 02:03:56 please enter a post title
- 02:04:00 now i'll just copy that matte error and
- 02:04:02 also paste it below my text area here
- 02:04:06 and on the text area i will now also
- 02:04:09 add a local reference content equal to
- 02:04:13 ngmodel here too
- 02:04:14 and therefore here we check whether the
- 02:04:16 content is invalid
- 02:04:17 and now with that if i save that
- 02:04:22 and go back to my application and i
- 02:04:25 submit this
- 02:04:25 you see we got the error messages below
- 02:04:28 the inputs too
- 02:04:29 this is really cool if i do enter some
- 02:04:31 valid information here
- 02:04:32 i can submit so this is form handling
- 02:04:35 with the help of
- 02:04:36 angular forms so called template driven
- 02:04:40 form to be very precise because
- 02:04:41 everything is inferred from within your
- 02:04:43 template there is an alternative to
- 02:04:45 which i will come back later
- 02:04:47 so template driven forms and a little
- 02:04:49 help
- 02:04:50 of the angle material package when it
- 02:04:52 comes to beautifully handle
- 02:04:54 errors
- 02:05:03 now one thing i noticed is that i
- 02:05:05 accidentally removed my margin here at
- 02:05:07 the top because i set margin to auto
- 02:05:09 well of course we can fix that by adding
- 02:05:11 one ram here on the margin
- 02:05:14 to top and bottom actually and then
- 02:05:15 audit left and right
- 02:05:17 that's a quick thing and that's not the
- 02:05:18 main thing i want to focus on here
- 02:05:20 instead what i want to focus on is how
- 02:05:22 we get new posts
- 02:05:24 from the post create component to the
- 02:05:26 post list component here
- 02:05:28 right now we get this chain of property
- 02:05:30 and event binding we're emitting a new
- 02:05:33 post here and we're passing it to the
- 02:05:35 parent component
- 02:05:36 and then we're passing it down to the
- 02:05:37 post list component and this clearly
- 02:05:39 works but
- 02:05:41 i guess you can imagine that in bigger
- 02:05:43 and bigger applications
- 02:05:45 this becomes more and more cumbersome
- 02:05:46 because you got longer and longer chains
- 02:05:49 of property and event binding
- 02:05:50 to get an element from component a to b
- 02:05:52 to c to d
- 02:05:54 to e and that is not really what you
- 02:05:56 want to build typically so
- 02:05:58 it would be nice if we had an easier way
- 02:06:01 of passing data around or an
- 02:06:02 alternative at least and such an
- 02:06:04 alternative which we will use quite a
- 02:06:06 bit throughout the course for other
- 02:06:07 things too
- 02:06:08 is a service a service is
- 02:06:12 a class which you add to your angular
- 02:06:14 application
- 02:06:15 which you let inject by angular into
- 02:06:18 components
- 02:06:19 i'll come back to what inject means and
- 02:06:21 which is
- 02:06:22 able to centralize some tasks and
- 02:06:24 provide easy access to data from within
- 02:06:27 different components without property
- 02:06:29 and event binding
- 02:06:30 i will create a posts service in the
- 02:06:33 posts
- 02:06:34 folder by creating a new file posts
- 02:06:37 dot service dot ts and that name is up
- 02:06:40 to you but the convention is to name it
- 02:06:42 dot service
- 02:06:43 ts now a service is just a typescript
- 02:06:47 class so export a class
- 02:06:49 posts service just like that now in
- 02:06:51 there
- 02:06:52 i want to store a list of posts so i'll
- 02:06:55 add posts
- 02:06:56 and set the type to post array
- 02:07:00 now for this i need to import my post
- 02:07:03 model so i import post from
- 02:07:06 dot slash post model like that
- 02:07:10 and this array initially is empty let's
- 02:07:12 say you could also set it to undefined
- 02:07:15 but i'll set it to empty
- 02:07:17 now here i actually want to turn this
- 02:07:20 into a private property which means
- 02:07:22 you can't edit it from outside i do this
- 02:07:24 by adding private in front of posts
- 02:07:27 now this post service if we add to
- 02:07:29 another file can't access posts
- 02:07:31 instead i will create a new method get
- 02:07:34 posts which allows someone who's
- 02:07:36 interested
- 02:07:37 to retrieve the posts so in here i will
- 02:07:40 return
- 02:07:42 this post so i can do this because now
- 02:07:44 i'm accessing the post from inside
- 02:07:46 but i actually don't want to return the
- 02:07:47 original array because as you might know
- 02:07:50 arrays and objects in javascript and
- 02:07:53 also in typescript
- 02:07:54 are reference types and if you don't
- 02:07:56 know what reference types and primitives
- 02:07:58 are
- 02:07:59 an article and a video i created can be
- 02:08:01 found in the last lecture of this module
- 02:08:03 it's really useful for understanding
- 02:08:04 this
- 02:08:05 essentially a reference type is a type
- 02:08:08 where if you copy it you don't really
- 02:08:10 copy it
- 02:08:11 the object in memory will stay the same
- 02:08:14 you just
- 02:08:15 copied the address so the pointer
- 02:08:17 pointing at that object
- 02:08:19 so to make a true copy of the posts i
- 02:08:22 will use
- 02:08:22 a typescript and next-gen javascript
- 02:08:25 feature
- 02:08:26 called the spread operator
- 02:08:29 i add square brackets to create a new
- 02:08:32 array
- 02:08:33 and then three dots to take all the
- 02:08:34 elements of another array the posts
- 02:08:36 array here
- 02:08:38 pull them out of that array and add them
- 02:08:40 to this new array
- 02:08:41 so i'm creating a new array with the old
- 02:08:43 objects
- 02:08:44 and therefore this array has been copied
- 02:08:47 important
- 02:08:48 not the objects these are still the old
- 02:08:50 objects
- 02:08:51 but at least the array is copied so if i
- 02:08:53 now edit this array if i
- 02:08:55 add new elements or remove elements from
- 02:08:58 within another component
- 02:09:00 this will not work this will not affect
- 02:09:03 my original array here so that's a
- 02:09:05 little bonus you don't have to do that
- 02:09:07 but it's a good practice to do that to
- 02:09:09 try to be immutable be clear about the
- 02:09:12 fact that you don't want people to
- 02:09:13 directly edit this posts array
- 02:09:15 and with that we get a get posts method
- 02:09:18 getting posts is nice but posting them
- 02:09:20 would also be
- 02:09:21 nice right so i will also add a add post
- 02:09:24 method where i expect to get a post
- 02:09:26 as an argument you could also just get
- 02:09:30 a title and some content and then
- 02:09:34 construct the post here whatever you
- 02:09:36 prefer
- 02:09:37 i will do the latter so i will create a
- 02:09:39 new post here
- 02:09:40 a post is of type post and it's a
- 02:09:42 javascript object
- 02:09:43 which has to have you know a title
- 02:09:45 because that's defined in our post
- 02:09:47 model and it will store the title there
- 02:09:50 and a content property into which i will
- 02:09:52 store
- 02:09:52 the content argument and now we can
- 02:09:54 reach out to our post here
- 02:09:56 or to our posts array and push that new
- 02:09:58 post into it
- 02:10:00 now if we do that we added this post
- 02:10:04 and now we get methods for getting all
- 02:10:06 posts and for adding a new post
- 02:10:08 now we could use that from both the post
- 02:10:10 list component and the post create
- 02:10:12 component
- 02:10:13 without having to pass data around with
- 02:10:15 property and event binding
- 02:10:17 for this we just need to get the service
- 02:10:19 into these components
- 02:10:21 and this is done with a feature called
- 02:10:23 dependency
- 02:10:24 injection now this means that you simply
- 02:10:27 go to the component where you want to
- 02:10:29 use that
- 02:10:29 let's say to the post list component and
- 02:10:32 you add a constructor
- 02:10:34 you do this with the constructor keyword
- 02:10:36 constructor simply is a function which
- 02:10:38 is called whenever angular creates a new
- 02:10:40 instance of this component
- 02:10:42 and here you can expect arguments but
- 02:10:44 since angular is the one
- 02:10:45 creating new instances of the component
- 02:10:48 angular has to give you these arguments
- 02:10:50 and angular has a complex dependency
- 02:10:52 injection system
- 02:10:54 which is able to actually find out what
- 02:10:56 you wanted and indeed give you that
- 02:10:58 so here what you do is you define
- 02:11:02 the service you want to have and i
- 02:11:05 simply add an argument with any name you
- 02:11:07 want i'll name it posts
- 02:11:08 service though because that is what i
- 02:11:10 want to have and now you have to define
- 02:11:12 the type here
- 02:11:13 to give angular a hint about what it
- 02:11:16 actually should give you
- 02:11:18 so here i'll set the type to post
- 02:11:20 service
- 02:11:21 and i need to import this so i'll go up
- 02:11:23 there
- 02:11:24 and import postservice
- 02:11:28 from posts
- 02:11:31 dot service like that
- 02:11:35 now this will actually tell angular hey
- 02:11:38 i want to have a
- 02:11:39 post service instance because you set
- 02:11:41 the type and angle will try its best to
- 02:11:43 give you an instance of the service
- 02:11:45 however i also want to store this
- 02:11:49 in a property of my class here
- 02:11:52 so i can add a new property here which i
- 02:11:55 can also name
- 02:11:56 posts service which is of type
- 02:11:59 post service and is empty at the
- 02:12:01 beginning and then here
- 02:12:03 we can set this posts service equal to
- 02:12:06 the post service instance i'm getting
- 02:12:08 here
- 02:12:08 now this is a bit of cumbersome
- 02:12:11 typescript offers a shortcut for this
- 02:12:13 we can omit all that code and actually
- 02:12:16 get the exact
- 02:12:17 same result by adding a keyword
- 02:12:20 in front of post service the public
- 02:12:22 keyword
- 02:12:23 will automatically create a new property
- 02:12:27 in this component and store the incoming
- 02:12:29 value in that property
- 02:12:31 now that's all nice and angular will try
- 02:12:34 to fulfill this requirement
- 02:12:35 but actually it won't be aware of the
- 02:12:38 post service because it doesn't scan all
- 02:12:40 your files
- 02:12:41 so you have to make angular aware and
- 02:12:44 there are two ways of doing that
- 02:12:45 you can go to app module and add the
- 02:12:48 posts service there
- 02:12:49 not in declarations and not in imports
- 02:12:52 but in the providers array providers are
- 02:12:55 for services
- 02:12:56 there you could simply add posts service
- 02:12:59 and also add the import pointing to that
- 02:13:01 file
- 02:13:03 and then this would allow angular to
- 02:13:05 find that service
- 02:13:06 that's option number one and there's
- 02:13:08 nothing wrong with it
- 02:13:10 you can also take an even easier route
- 02:13:12 and go to the post
- 02:13:13 service and add an argument to it at
- 02:13:17 injectable which is imported from at
- 02:13:21 angular core don't forget the
- 02:13:24 parentheses
- 02:13:25 and there you don't have to but you can
- 02:13:27 pass
- 02:13:28 a javascript object to configure this
- 02:13:31 and you can then
- 02:13:32 set provided in
- 02:13:35 and set this to a string named root or
- 02:13:37 with the content of root and
- 02:13:38 make sure to not mistype root as
- 02:13:40 important and this simply will do the
- 02:13:42 same it provides this on the root
- 02:13:44 level and this not only means that
- 02:13:46 angular finds this
- 02:13:47 this also means and the same was true if
- 02:13:49 you added it to providers
- 02:13:51 that angular doesn't only find it but
- 02:13:53 that it will only create one instance of
- 02:13:55 the service for the entire app
- 02:13:57 so wherever you inject this you're going
- 02:13:59 to use the same instance
- 02:14:00 and this is really important because
- 02:14:02 since we manage our posts array in the
- 02:14:04 service
- 02:14:04 having multiple instances would be bad
- 02:14:07 because we would have multiple copies
- 02:14:08 with different
- 02:14:09 arrays in there now we have one of the
- 02:14:12 same instance
- 02:14:13 and we got it injected into post list
- 02:14:16 and there we got our post service now
- 02:14:19 all we need to do is call
- 02:14:20 get posts let's do that and wire up the
- 02:14:23 rest
- 02:14:24 in the next lectures
- 02:14:34 so time to reach out to our service and
- 02:14:36 call get posts and for this
- 02:14:38 i will not actually use the constructor
- 02:14:40 though that would be possible
- 02:14:42 but it's a better practice to use a
- 02:14:44 special life cycle hook
- 02:14:45 angular provides there are life cycle
- 02:14:47 hooks which angular will automatically
- 02:14:49 execute when it creates a component
- 02:14:51 and one of them is the on init lifecycle
- 02:14:53 hook we added by
- 02:14:55 implementing an interface this is
- 02:14:57 essentially a contract
- 02:14:58 this class now signs it's called on init
- 02:15:02 and it's imported from at angular core
- 02:15:05 and this implementation now actually
- 02:15:08 causes an error because now we're
- 02:15:10 required to add a special method
- 02:15:12 to our class here the ngon init method
- 02:15:15 and once we add this everything is great
- 02:15:17 again so now ngon init this is a
- 02:15:20 function angular will automatically
- 02:15:22 execute for us when it creates this
- 02:15:24 component
- 02:15:25 and it's recommended to do basic
- 02:15:26 initialization tasks
- 02:15:28 in ngon init and there i can now set
- 02:15:31 this posts equal to
- 02:15:32 this posts service remember
- 02:15:36 this automatically created a property of
- 02:15:38 the same name
- 02:15:39 and there get posts like this
- 02:15:44 now we fetch all the posts of course
- 02:15:48 our posts are empty at the beginning
- 02:15:49 though so we'll need to
- 02:15:51 add posts and for this we can go to post
- 02:15:53 create
- 02:15:54 and there i also want to
- 02:15:58 connect to my service so i'll add my
- 02:16:00 constructor here too
- 02:16:02 use the shortcut to automatically create
- 02:16:04 a property named posts
- 02:16:06 service and add to type post service
- 02:16:10 import is added automatically by my ide
- 02:16:14 don't forget these curly braces and now
- 02:16:16 posts
- 02:16:17 service is injected here too now here
- 02:16:20 i want to reach out to the post service
- 02:16:23 not an ng on init but whenever
- 02:16:25 when i created a new post so here i will
- 02:16:28 actually remove add output i don't need
- 02:16:30 it anymore
- 02:16:31 don't need the whole event emitter
- 02:16:32 anymore remove both imports
- 02:16:35 and instead instead of emitting
- 02:16:38 i will now simply call this post
- 02:16:41 service add post and pass my
- 02:16:45 post there or we're actually expecting a
- 02:16:47 title and a string
- 02:16:49 and a content so i can also just pass
- 02:16:52 these
- 02:16:52 values here title and content as
- 02:16:55 arguments
- 02:16:56 i don't even need to construct the post
- 02:16:57 in this file therefore
- 02:17:00 so this means we can get rid of the post
- 02:17:02 import here too
- 02:17:04 so now we're calling add post from
- 02:17:06 within the post create component
- 02:17:08 we're calling get posts from within the
- 02:17:10 post list component
- 02:17:12 and in the post service we're connecting
- 02:17:14 this let's give this a try
- 02:17:17 if i enter something here and i click
- 02:17:19 save post
- 02:17:20 nothing happens and what's wrong here
- 02:17:24 now what's wrong is that we're getting
- 02:17:28 posts
- 02:17:28 when the post list component is created
- 02:17:30 with ngon in it
- 02:17:31 and at this point of time we got an
- 02:17:33 empty list there right it's an empty
- 02:17:35 list of posts
- 02:17:36 when we later add posts this doesn't do
- 02:17:39 anything
- 02:17:39 because we created a copy of posts and
- 02:17:42 returned that
- 02:17:43 so if we added the original array
- 02:17:45 thereafter this
- 02:17:46 doesn't well affect anything on our post
- 02:17:49 list component
- 02:17:51 by the way we can also remove input here
- 02:17:54 so
- 02:17:54 this is the reason why it's not working
- 02:17:56 because
- 02:17:57 we fetch the posts a copy of them before
- 02:18:00 we edit
- 02:18:01 them now there are a couple of ways of
- 02:18:03 solving that
- 02:18:04 we could not fetch a copy for example
- 02:18:07 if we do that you will see that now if
- 02:18:10 this reloads
- 02:18:12 i get an error right because i should go
- 02:18:14 to my app component html file and remove
- 02:18:16 the bindings here we don't need that
- 02:18:18 anymore to manage our posts
- 02:18:20 let's also remove it in the typescript
- 02:18:24 file of the app component and remove the
- 02:18:25 post import so
- 02:18:27 let's save all that so now if i go back
- 02:18:29 it loads again
- 02:18:30 and if i now enter something here you
- 02:18:32 see the posts are added again
- 02:18:34 but this is not the cleanest way of
- 02:18:36 doing that i'm a fan of copying this
- 02:18:38 to avoid unwanted manipulation of the
- 02:18:40 posts in
- 02:18:41 any component which is fetching our
- 02:18:43 posts so a better way is to use
- 02:18:46 an event-driven approach where we
- 02:18:49 actively push the information about new
- 02:18:51 posts being available
- 02:18:53 to the components which are interested
- 02:18:56 and for that we could use the event
- 02:18:57 emitter but the event emitter
- 02:18:59 is really meant to be used in
- 02:19:00 conjunction with that at output
- 02:19:02 decorator instead i'll use a feature
- 02:19:05 provided by another package which
- 02:19:08 is not part of angular but a core
- 02:19:10 dependency the rxjs package
- 02:19:14 you find here it's actually it's
- 02:19:16 installed from
- 02:19:17 the beginning rxjs is all about
- 02:19:20 observables and this is a concept which
- 02:19:22 can be a bit more complex to
- 02:19:24 grasp it's essentially about objects
- 02:19:27 that help us
- 02:19:28 pass data around you could say and we'll
- 02:19:31 dive deeper into observables step by
- 02:19:33 step
- 02:19:33 and i also dive deeper into them in my
- 02:19:35 complete guide on angular here on udb
- 02:19:37 and all the complete youtube series i
- 02:19:40 got
- 02:19:41 so we simply need to import something
- 02:19:43 from that
- 02:19:44 rxjs package to get started
- 02:19:48 and that something
- 02:19:51 is a subject now that essentially is an
- 02:19:54 event emitter you could say
- 02:19:56 but one which is actually for broader
- 02:19:58 usage than the one
- 02:19:59 angular ships with and now
- 02:20:02 i will create this subject here as a
- 02:20:06 private property too
- 02:20:08 i'll name this posts updated
- 02:20:11 again taking a property name here which
- 02:20:13 sounds like an event this is not
- 02:20:15 required
- 02:20:16 but also not the worst idea and i'll
- 02:20:18 create a new instance of my subject
- 02:20:21 just as the event emitter this is a
- 02:20:23 generic type and here i
- 02:20:24 plan on passing a list of posts as
- 02:20:28 a payload so we get the posts updated
- 02:20:31 subject here
- 02:20:32 and now when we have add post here or
- 02:20:36 when we
- 02:20:37 call this i don't just want to update my
- 02:20:39 posts
- 02:20:40 i also thereafter want to take my
- 02:20:42 subject
- 02:20:43 post updated and there it's not emit but
- 02:20:46 next
- 02:20:46 and this pushes a new value it emits a
- 02:20:49 new value
- 02:20:50 and this value is a copy of my posts
- 02:20:53 after i updated them
- 02:20:56 so this is now the subject we can still
- 02:20:59 leave get posts in there even though
- 02:21:01 it's not that useful right now but
- 02:21:03 that could change later on what i now
- 02:21:05 want to do is of course i want to be
- 02:21:07 able to listen to that subject
- 02:21:08 because it's emitting whenever we add a
- 02:21:10 post how do i listen
- 02:21:12 to it it's private so we can't directly
- 02:21:14 access it
- 02:21:15 to prevent other components from
- 02:21:17 emitting data with it
- 02:21:19 what i'll add is i'll add a new method
- 02:21:21 here
- 02:21:22 get post update listener the name is up
- 02:21:25 to you of course
- 02:21:26 and there i will return this posts
- 02:21:30 updated and then there's a special
- 02:21:32 method we can call
- 02:21:33 as observable and now it returns an
- 02:21:36 object to which we can listen
- 02:21:37 but where we can't emit we can still
- 02:21:39 emit from inside this file
- 02:21:41 but not from files which received their
- 02:21:43 reference with the help of this method
- 02:21:46 so now we got get post update listener
- 02:21:48 we can now go to the post list component
- 02:21:51 again
- 02:21:52 and i will still fetch that list of
- 02:21:54 posts at the beginning
- 02:21:55 even though it's guaranteed to be empty
- 02:21:56 right now
- 02:21:58 but what i will also do is i will set up
- 02:22:00 a listener to that
- 02:22:02 subject i do this by reaching out to
- 02:22:04 this post
- 02:22:05 service get post update listener
- 02:22:08 this returns this observable and there
- 02:22:10 we can call subscribe
- 02:22:12 this is a method which is made available
- 02:22:15 just putting this into a new line to
- 02:22:16 make it easier to read
- 02:22:17 it still is part of this statement here
- 02:22:21 so subscribe now sets up a subscription
- 02:22:24 and subscribe actually takes
- 02:22:25 three arguments possible arguments the
- 02:22:28 first one is a function which gets
- 02:22:30 executed whenever new data is emitted
- 02:22:32 the second argument will be called
- 02:22:34 whenever an error is emitted this will
- 02:22:36 never happen here
- 02:22:37 and the third argument will be a
- 02:22:39 function that is called whenever
- 02:22:41 the observable is completed if whenever
- 02:22:44 there are no more values to be expected
- 02:22:46 this will also never be the case here
- 02:22:49 because this is an
- 02:22:50 infinitely living subject so to say we
- 02:22:52 can always create new posts
- 02:22:54 so we only add the first argument a
- 02:22:57 function which is called whenever
- 02:22:58 a new value is received and i'm using an
- 02:23:01 arrow function here
- 02:23:03 we receive some data here the posts
- 02:23:06 right because in the post service we are
- 02:23:08 emitting
- 02:23:10 our new posts a copy of them
- 02:23:13 so post is what we receive so i'll set
- 02:23:16 the type to post array to be very clear
- 02:23:18 about what we're getting here
- 02:23:20 and in here i can then set
- 02:23:23 this posts equal to the posts i just
- 02:23:26 received to update them
- 02:23:28 whenever this got a new value received a
- 02:23:31 new value
- 02:23:33 now one important thing this
- 02:23:34 subscription here actually doesn't
- 02:23:36 cancel
- 02:23:37 whenever this component is teared down
- 02:23:40 now right now this component never
- 02:23:41 disappears because we got only one page
- 02:23:43 we get no way of removing that component
- 02:23:45 from the ui
- 02:23:47 but later we will later there will be
- 02:23:49 more components different pages
- 02:23:51 and we want to ensure that whenever this
- 02:23:53 component is not part of the dom
- 02:23:55 the subscriptions which we set up in it
- 02:23:58 are also not living anymore
- 02:24:00 otherwise we create a memory leak so we
- 02:24:03 will actually store that subscription
- 02:24:05 in a new property which will be of type
- 02:24:08 subscription
- 02:24:09 so i'll import subscription
- 02:24:13 from rxjs like this here subscription
- 02:24:19 and now i will create a new property
- 02:24:21 here private property maybe it doesn't
- 02:24:23 matter
- 02:24:24 posts sub which is of type subscription
- 02:24:29 and it's undefined at the beginning and
- 02:24:31 here in engion in it
- 02:24:33 i will set this posts sub equal to this
- 02:24:37 post service and the subscription we're
- 02:24:38 defining here
- 02:24:39 now we just need to unsubscribe whenever
- 02:24:42 this component is destroyed
- 02:24:43 and there is another live cycle look we
- 02:24:45 can use for that
- 02:24:47 we add it by implementing on destroy
- 02:24:50 this forces us to add one hour method
- 02:24:53 the
- 02:24:53 ng on destroy method which is called
- 02:24:56 whenever this component is about to get
- 02:24:58 removed
- 02:24:59 and there i will reach out to my posts
- 02:25:01 sub
- 02:25:02 not the service the sub and call
- 02:25:05 unsubscribe and this will remove the
- 02:25:08 subscription and prevent
- 02:25:09 memory leaks and with this added if i go
- 02:25:12 back
- 02:25:14 we can try this add a post does this
- 02:25:17 work and hit save post and you see
- 02:25:20 we can add new posts here of course also
- 02:25:24 with
- 02:25:24 other content then the old one
- 02:25:28 and now this is working with the service
- 02:25:30 and whilst the setup
- 02:25:31 is of course a bit more complex it saves
- 02:25:34 us a lot of time since we don't have to
- 02:25:36 build
- 02:25:36 these chains of property and event
- 02:25:38 binding and you already learned quite a
- 02:25:40 bit about observables here
- 02:25:42 with this event emitter we're using here
- 02:25:45 so now
- 02:25:45 let's move on
- 02:25:55 in the last lectures we learned about
- 02:25:57 this subject subscriptions
- 02:25:59 and this seems to be related to
- 02:26:01 something called observables
- 02:26:03 time for a closer look so what's this
- 02:26:06 observable
- 02:26:07 thing as you could probably tell by the
- 02:26:09 code we wrote it's all about
- 02:26:11 us emitting data and listening to that
- 02:26:14 data in different places of our
- 02:26:16 application
- 02:26:17 which makes it pretty helpful because we
- 02:26:19 can well subscribe to certain updates
- 02:26:22 changes and push these changes from a
- 02:26:24 totally different place
- 02:26:26 here's more theory on that so we
- 02:26:28 typically think in
- 02:26:29 observables and observers the observer
- 02:26:33 is essentially the thing subscribing to
- 02:26:35 an observable
- 02:26:36 or the thing which establishes this
- 02:26:38 subscription and manages it you could
- 02:26:39 say
- 02:26:40 there are three methods which are called
- 02:26:42 on the observer's
- 02:26:43 side and that's next error and complete
- 02:26:46 now we called next on the subject in the
- 02:26:49 last lectures
- 02:26:51 and the subject is kind of the
- 02:26:53 observable you could say
- 02:26:54 but it's the observer who then does
- 02:26:56 something upon the next call
- 02:26:59 in that subscription callback we passed
- 02:27:01 right that first
- 02:27:02 argument we passed to subscribe that is
- 02:27:05 the logic we want to execute
- 02:27:07 whenever next is executed on the subject
- 02:27:10 so to say so we invoke next through the
- 02:27:14 observable or through the subject i'll
- 02:27:16 come to the difference
- 02:27:17 and the observer is what we basically
- 02:27:20 pass into subscribe
- 02:27:22 so it's a collection of functions that
- 02:27:24 can do something upon these method calls
- 02:27:27 and as i also explained briefly we
- 02:27:29 cannot just emit
- 02:27:31 next data so a new package of data so to
- 02:27:34 say
- 02:27:35 we could also have an observable where
- 02:27:36 we want to throw an
- 02:27:38 error maybe because we're doing some
- 02:27:40 http calls behind the scenes that failed
- 02:27:43 or we could also emit a complete event
- 02:27:46 to basically say hey i'm done there are
- 02:27:49 no more
- 02:27:50 data packages to be emitted so no more
- 02:27:52 next calls
- 02:27:54 now a typical example but of course not
- 02:27:56 limited to that
- 02:27:58 is an observable that wraps a callback
- 02:28:00 of an http request
- 02:28:02 so we could wrap a normal xml http
- 02:28:06 request an
- 02:28:06 ajax request with an observable that
- 02:28:09 basically takes that callback and
- 02:28:11 whenever that request gives us back a
- 02:28:13 response
- 02:28:14 we instead use that observable to emit
- 02:28:16 the response data
- 02:28:18 or a possible error as a next or
- 02:28:21 error message and that is essentially
- 02:28:23 what we could do
- 02:28:24 we could also complete the observable
- 02:28:26 once the response is there because of
- 02:28:28 course
- 02:28:29 if the response is there this http
- 02:28:31 request will not yield any other
- 02:28:33 responses
- 02:28:34 as i said it could also fail and that is
- 02:28:37 how we could manage such a http request
- 02:28:40 now in our app we didn't manage an http
- 02:28:42 request though
- 02:28:43 we managed a subject or our own event
- 02:28:46 emitter therefore
- 02:28:47 now a subject is really just a special
- 02:28:49 kind of observable
- 02:28:51 normal observable is kind of passive
- 02:28:54 you wrap a callback or an event source
- 02:28:58 like a click listener with it so you
- 02:29:00 don't actively
- 02:29:01 trigger when a new data package is
- 02:29:04 emitted
- 02:29:04 that happens when your http requests
- 02:29:07 gets a response or when the user clicks
- 02:29:09 something
- 02:29:10 instead you just yeah well set up this
- 02:29:13 listener
- 02:29:13 and then you can subscribe to it a
- 02:29:16 subject is more active
- 02:29:17 we also subscribe to a subject but there
- 02:29:20 we can manually call
- 02:29:22 next and that makes it a perfect event
- 02:29:25 emitter because we cannot just subscribe
- 02:29:27 and
- 02:29:28 wait for something which we can't
- 02:29:30 directly influence
- 02:29:31 instead we can directly influence when a
- 02:29:34 new data package is emitted and that's
- 02:29:36 exactly what we need in our application
- 02:29:38 when we add a new post
- 02:29:41 then we actively want to notify our
- 02:29:43 entire application
- 02:29:45 and that is what we can do with a
- 02:29:46 subject so in general
- 02:29:48 you can think of observables and
- 02:29:50 therefore also subjects
- 02:29:52 as streams of data or of values
- 02:29:55 so we got one value and we can have more
- 02:29:57 values which are emitted over time
- 02:29:59 depending on the observable and the data
- 02:30:02 source it covers
- 02:30:03 then we have the observer so that's
- 02:30:05 essentially this set of functions we can
- 02:30:07 call
- 02:30:07 next error and complete and for a normal
- 02:30:11 value we typically would call
- 02:30:12 next and if we have an observable that
- 02:30:15 wraps
- 02:30:15 something like a http request then it
- 02:30:18 would do that for us
- 02:30:19 and as i said we can have more than one
- 02:30:21 value over the course of
- 02:30:23 our application that depends on how we
- 02:30:26 are using that observable
- 02:30:28 eventually it may end but of course
- 02:30:29 there are also observables
- 02:30:31 that may never end for example if you're
- 02:30:33 wrapping a normal click listener with it
- 02:30:35 well then this will typically never end
- 02:30:37 if you got an observable that ends
- 02:30:38 well then the complete function here
- 02:30:40 will be called
- 02:30:42 and this is how it works this is how we
- 02:30:45 work with
- 02:30:46 observables how we should think about
- 02:30:47 them if you want to learn way more about
- 02:30:49 rxjs observables in the last lecture of
- 02:30:52 this module
- 02:30:53 you find a link to a in-depth series i
- 02:30:57 created on youtube but that's the core
- 02:30:59 mental model
- 02:31:00 to wrap your head around for now we will
- 02:31:02 mostly use the subject we will
- 02:31:04 indirectly use some observables and i
- 02:31:06 will explain what they do when we use
- 02:31:08 them
- 02:31:08 but in the end think of it as a stream
- 02:31:11 of data which you can
- 02:31:12 actively manage in the case of a subject
- 02:31:14 or which is managed for you if you're
- 02:31:16 wrapping some well source you can't
- 02:31:19 directly influence
- 02:31:20 and then you can decide what you want to
- 02:31:22 do when new data is emitted
- 02:31:24 in your subscription so now with this
- 02:31:27 closer look at observables
- 02:31:28 let's finish up our form here on the
- 02:31:31 angular front and then do some first
- 02:31:33 polishing
- 02:31:33 before we move to the back end and add
- 02:31:36 node
- 02:31:37 so that we don't just have a front end
- 02:31:39 but we also start working
- 02:31:41 on the back end
- 02:31:51 so here's our front end our angular app
- 02:31:54 as we left it it's far from being
- 02:31:56 finished and we
- 02:31:57 will revisit it later in the course but
- 02:31:59 for now let's do some polishing
- 02:32:01 one polishing or one addition i want to
- 02:32:03 do is would be nice to have some labels
- 02:32:05 here right
- 02:32:06 and actually you can add labels easily
- 02:32:09 cue your
- 02:32:10 forms in angular material by going to
- 02:32:13 the html code
- 02:32:15 and adding a placeholder attribute
- 02:32:18 and there we could say title or maybe
- 02:32:21 post
- 02:32:21 title and we can also add that to the
- 02:32:24 text area
- 02:32:25 and say post content there and you will
- 02:32:28 see that if you add such a placeholder
- 02:32:30 you get it as a label here and you
- 02:32:32 automatically got this
- 02:32:33 floating label look here which is quite
- 02:32:35 neat
- 02:32:36 now one other thing i want to do is if i
- 02:32:38 enter a new post here
- 02:32:40 right now you can see the values stick
- 02:32:42 around
- 02:32:43 this forum doesn't get cleared and we
- 02:32:46 can clear it
- 02:32:47 in on add post where we get access to
- 02:32:50 that forum
- 02:32:51 by accessing form and then calling
- 02:32:54 reset form like this
- 02:32:57 if we now save that let's try this again
- 02:33:01 let's enter something here let's click
- 02:33:03 save post
- 02:33:04 and you see this now resets the form and
- 02:33:07 also
- 02:33:07 the validity not just the values it
- 02:33:09 doesn't just clear the form it also
- 02:33:11 resets the validity
- 02:33:12 which of course is exactly the behavior
- 02:33:14 we want now that's almost
- 02:33:16 all one other thing i want to add for
- 02:33:19 now already
- 02:33:20 is i want to add a action bar to the
- 02:33:22 post
- 02:33:23 whilst the functionality is missing
- 02:33:26 right now
- 02:33:26 we will add it later i want to be able
- 02:33:29 to edit
- 02:33:30 and delete such posts again the logic
- 02:33:32 behind that
- 02:33:33 and the code will be added later that
- 02:33:36 means i want to have
- 02:33:37 edit and a delete button here on this
- 02:33:39 expand panel or on this expansion panel
- 02:33:42 if we check the official docs we can see
- 02:33:44 that there is
- 02:33:45 a action bar or action row component
- 02:33:49 we can nest into our expansion panel
- 02:33:52 that looks pretty promising
- 02:33:54 with that code copied if we go back to
- 02:33:56 the post list component here
- 02:33:58 we can add that below the paragraph in
- 02:34:01 the expansion panel
- 02:34:02 and we get a button here in the code
- 02:34:04 snippet 2 and it will simply say
- 02:34:06 edit i will actually add two buttons
- 02:34:09 because i also want to have a delete
- 02:34:10 button here
- 02:34:12 you can also make this all caps to be
- 02:34:14 closer to the original material style by
- 02:34:16 the way
- 02:34:17 where buttons tend to be all capitalized
- 02:34:20 now the buttons if we add them like this
- 02:34:24 can be seen let's quickly add a post
- 02:34:26 here
- 02:34:27 here are the buttons but they're not
- 02:34:29 looking that spectacular
- 02:34:31 to make them look a bit more spectacular
- 02:34:33 what i will do is i will add some colors
- 02:34:36 for the edit button i'll assign my
- 02:34:39 primary color
- 02:34:40 or maybe the accent color whichever one
- 02:34:43 you prefer
- 02:34:44 and the delete button here i will use my
- 02:34:46 worn color
- 02:34:47 because people should certainly be
- 02:34:49 careful when clicking these buttons
- 02:34:50 or this button specifically so now with
- 02:34:53 that added
- 02:34:54 if we add one more post we see edit and
- 02:34:57 delete now
- 02:34:58 since my accent color is this pink color
- 02:35:00 it looks very much like the delete
- 02:35:02 button
- 02:35:03 so i will go for primary here to have a
- 02:35:05 greater
- 02:35:06 difference between the colors so let's
- 02:35:09 add one more post here
- 02:35:12 yeah that looks better and that is the
- 02:35:14 last thing i wanted to prepare
- 02:35:16 now again we will improve this code a
- 02:35:18 lot
- 02:35:19 later we will add a edit and delete
- 02:35:21 functionality
- 02:35:22 we will also add more components more
- 02:35:25 pages on our front end
- 02:35:27 but for now it's enough about angular
- 02:35:30 let's move on to the back end
- 02:35:32 let's move on to node and understand how
- 02:35:34 that works and fits into
- 02:35:36 our angular application
- 02:35:40 you