Coding

ANGULAR 2 FRONTEND | Laravel + Angular 2 / Vue.js 2

  • 00:00:01 welcome back to this series where we're
  • 00:00:03 going to connect our angle Q or view
  • 00:00:06 chess front-end to our level back and
  • 00:00:09 see how level and what your view chess
  • 00:00:12 can work together now we created our
  • 00:00:15 level back end in the last video now
  • 00:00:18 it's time to create our angular 2
  • 00:00:20 front-end and to connect it I got a
  • 00:00:23 brand new angle to application created
  • 00:00:26 with the CLI I only removed some content
  • 00:00:29 in the app component which we have there
  • 00:00:31 by default a daddy dave here with the
  • 00:00:34 idea app and stat and then the
  • 00:00:36 index.html file I added this import you
  • 00:00:39 get bootstrap to get some basic styling
  • 00:00:42 now with that what I want to do is I
  • 00:00:44 want to start by creating a couple of
  • 00:00:47 components so I'll use the CLI for that
  • 00:00:49 and generate or just G a new component
  • 00:00:53 or just C and then we'll need a quote
  • 00:00:57 component for an individual quote in our
  • 00:01:00 list of quotes so that's something I'll
  • 00:01:03 create then I'm going to create a quotes
  • 00:01:06 component holding that list of single
  • 00:01:09 quotes and I'll add a new quote
  • 00:01:12 component to be able to create a new
  • 00:01:15 quote guess what so that gave me those
  • 00:01:17 free new folders there I'll quickly
  • 00:01:20 remove these spec files could have also
  • 00:01:22 just a TC like command but whatever and
  • 00:01:25 with that we get our base well skeleton
  • 00:01:28 aware the files we need for now let's
  • 00:01:31 fill them with some life
  • 00:01:32 so in the app component HTML file I want
  • 00:01:35 to use the bootstrap grid and for that
  • 00:01:39 I'll create a new dev with the class
  • 00:01:40 container then row and then call XS 12
  • 00:01:44 to have a 12 column broad well column e
  • 00:01:50 or I guess a full-screen column
  • 00:01:53 basically on all devices on all screen
  • 00:01:55 widths and in there I want to place a
  • 00:01:59 router outlet that we haven't added the
  • 00:02:01 router yet we will do so there soon so
  • 00:02:04 this will be the place where I want to
  • 00:02:05 render already quotes component with all
  • 00:02:08 the quotes or the new quote component
  • 00:02:10 and for this to work I'll copy this row
  • 00:02:14 here at a horizontal line and in the top
  • 00:02:18 row I won't have the router outlet here
  • 00:02:20 when I want to have some links instead
  • 00:02:22 so here I will have a link which leads
  • 00:02:26 to the quotes and one which allows me to
  • 00:02:30 add a new quote so to switch between
  • 00:02:32 those two pages all set up so there I
  • 00:02:35 will add your router links as soon as I
  • 00:02:37 created the routes that is my first page
  • 00:02:41 here didi app component for now and in
  • 00:02:45 the CSS file
  • 00:02:46 I also added this app or this this
  • 00:02:51 little style here for the wrapping
  • 00:02:53 container with the idea of app to give
  • 00:02:55 it some margin to not sit on the edges
  • 00:02:58 so this is the app and just as a side
  • 00:03:00 note I will of course also add the
  • 00:03:03 finished app as a download to this
  • 00:03:05 project individual description now with
  • 00:03:08 this setup let's go to the code
  • 00:03:11 component to create a single quote here
  • 00:03:14 I'll add the panel class which trip
  • 00:03:17 gives me and then also the panel default
  • 00:03:20 class to make a default panel to just
  • 00:03:23 have this quote well stand out a bit and
  • 00:03:25 just have a nice border and so on and in
  • 00:03:28 there I'll leave the LED panel body what
  • 00:03:31 I want to output the quote content well
  • 00:03:34 quote is some object I haven't treated
  • 00:03:37 as a property yet but I will do so in a
  • 00:03:39 second and I will have a panel body
  • 00:03:42 there too now in the panel body and
  • 00:03:45 these are all just bootstrap classes
  • 00:03:47 keep that in mind
  • 00:03:48 in the panel body I want to have a
  • 00:03:51 couple of links to added save and so on
  • 00:03:54 but I'll come back to this let's work on
  • 00:03:57 the quote here I'm referring to some
  • 00:04:00 quote property which I haven't added yet
  • 00:04:02 and this quote property seems to have a
  • 00:04:06 content property so it seems to be an
  • 00:04:08 object because it makes sense I guess
  • 00:04:11 we're creating quotes each quote will
  • 00:04:13 have an ID and a content so why not pack
  • 00:04:17 it into an object and for this I will
  • 00:04:20 create an interface to have some kind of
  • 00:04:22 blueprint of how a quote should look
  • 00:04:24 like in my angular 2 application so I'll
  • 00:04:26 create this quote
  • 00:04:28 face dot typescript file in my root
  • 00:04:30 folder and in there I'll simply export
  • 00:04:34 not a class an interface which will then
  • 00:04:37 quote and here I'll define that I will
  • 00:04:40 have a content of type string and an
  • 00:04:42 idea of type number that's all this is
  • 00:04:44 my quote interface and this now allows
  • 00:04:47 me to go to my quote component add this
  • 00:04:49 new quote property which will be of type
  • 00:04:52 not quote component just of type quote
  • 00:04:55 self this newly created interface
  • 00:04:57 therefore I also need to add the import
  • 00:04:59 up here so this gives me the code object
  • 00:05:03 code property here in the individual
  • 00:05:05 quote component of course I want to have
  • 00:05:08 more than one quote I want to loop
  • 00:05:10 through all the quotes so time to go to
  • 00:05:12 the quotes plural component here to the
  • 00:05:17 template of that component to be precise
  • 00:05:19 and use our app quote selector the
  • 00:05:22 selector of this single quote component
  • 00:05:24 as set up here and loop through it so
  • 00:05:28 add an NG for loop do you loop through
  • 00:05:31 all the quotes we got here referring to
  • 00:05:34 the quotes property which of course I
  • 00:05:35 haven't created too so let's add a 2d
  • 00:05:39 quotes component here simpler quotes
  • 00:05:42 property which is of type quote also add
  • 00:05:47 the import here but not a single quote
  • 00:05:50 instead a quote array so now the quotes
  • 00:05:53 component get a property called quotes
  • 00:05:54 holding an array of quotes following our
  • 00:05:57 blueprint as setup in the quote
  • 00:05:59 interface now if that I can live through
  • 00:06:02 all the quotes outputted here and well
  • 00:06:07 therefore create a couple of quote
  • 00:06:09 components one for each quote we're
  • 00:06:11 getting from the server talking of
  • 00:06:14 getting well let me also add a
  • 00:06:16 horizontal line above the list and a
  • 00:06:19 button which will receive the button
  • 00:06:21 button primary classes bootstrap classes
  • 00:06:24 to get quotes and here I will call a
  • 00:06:28 method called on get quotes once you
  • 00:06:32 click on it this will allow me to reach
  • 00:06:34 out to the server and fetch all the
  • 00:06:36 quotes well now with that we get the
  • 00:06:40 basic setup for
  • 00:06:41 adding quotes and keep in mind we
  • 00:06:43 already get one code in our database
  • 00:06:45 because we created that quote in the
  • 00:06:48 last video when we created the backend
  • 00:06:50 so no need to hook up the added delete
  • 00:06:53 and cell buttons and the the add new
  • 00:06:56 quote page that's not needed instead
  • 00:06:58 let's see if that works
  • 00:07:01 as it should if we're able to get quotes
  • 00:07:03 now for it I will still need to set up
  • 00:07:06 the routing though because I already
  • 00:07:08 want to set all the pages up as they
  • 00:07:10 should be in the end or at least the
  • 00:07:11 structure of the pages so add a new file
  • 00:07:14 the app dot routing dot TS file and in
  • 00:07:18 there I will treat a new constant named
  • 00:07:20 app routes this name is up to you which
  • 00:07:22 will be of type routes holding all the
  • 00:07:25 application routes here and this is just
  • 00:07:28 an array of objects as you probably
  • 00:07:30 learned in one of my other videos or
  • 00:07:32 some other resource in the internet and
  • 00:07:34 here I will have a path and I need a
  • 00:07:37 empty path for my route route for the
  • 00:07:40 default route and here I wanna load the
  • 00:07:43 quotes component and I will add a second
  • 00:07:48 route don't forget to add those imports
  • 00:07:50 by the way the second route will lead to
  • 00:07:53 the new quote path and as the name
  • 00:07:58 suggests he rebel load the new quote
  • 00:08:00 component also add that import and of
  • 00:08:03 course also make sure that if you're not
  • 00:08:05 using the CLI you manually add all your
  • 00:08:08 quotes to the app module to the
  • 00:08:11 declarations array so with that the
  • 00:08:14 routes are set up now let's export the
  • 00:08:17 router the router module here import
  • 00:08:21 that from angler router to for route a
  • 00:08:25 Prout's to make them available and go to
  • 00:08:28 the app module and add it here in the
  • 00:08:30 imports array routing great so make sure
  • 00:08:34 to add the import to your app routing
  • 00:08:36 file to with that routing is set up and
  • 00:08:39 with that we would always be able to see
  • 00:08:43 that but right now might change again
  • 00:08:45 I'm not sure I also need to set the type
  • 00:08:49 for this exported cons there in the
  • 00:08:51 routing file and this is of type module
  • 00:08:54 with providers which
  • 00:08:55 needs to be imported from at angular
  • 00:08:57 core I'm not sure if this is intended
  • 00:09:00 because normally types could should be
  • 00:09:02 able to infer this from well there's
  • 00:09:05 Roger module for root method but right
  • 00:09:08 now I need to add it to not get an error
  • 00:09:10 so after saving this should now
  • 00:09:12 recompile I got these server already
  • 00:09:15 running and now we see looks good this
  • 00:09:19 is the get quotes component of course
  • 00:09:21 you don't see any quotes because we're
  • 00:09:23 not reaching out to the server yet this
  • 00:09:25 is what I want to work on next so to
  • 00:09:28 reach out to the server I will create a
  • 00:09:31 new service for this I'll name it quote
  • 00:09:34 service
  • 00:09:35 it'll also place it in the root file
  • 00:09:38 root folder excuse me and export this
  • 00:09:42 quote service class I'll add D at
  • 00:09:46 injectable decorator here to make sure I
  • 00:09:50 can also inject services into this
  • 00:09:53 service because I need access to the
  • 00:09:56 HTTP service to default angular to HTTP
  • 00:09:59 service which are there for import from
  • 00:10:02 at angular HTTP now I will add a get
  • 00:10:06 quotes method here and simply return
  • 00:10:09 this HTTP GET and now my URL which is
  • 00:10:15 either localhost if you haven't mapped
  • 00:10:18 it to a different domain or since I did
  • 00:10:20 map it here on my system it's level ng
  • 00:10:23 to – view death / API / quotes this is
  • 00:10:30 the API endpoint we set up in the last
  • 00:10:33 video in this series on our level
  • 00:10:35 back-end to get all the quotes I also
  • 00:10:39 want to map the response to transform it
  • 00:10:43 and for this to work I need to import
  • 00:10:45 rxjs /rx to unlock this map operator
  • 00:10:49 here I know I get a response of type
  • 00:10:52 response responses imported from at
  • 00:10:55 angular HTTP and then I can simply
  • 00:10:59 transform it so here I want to return
  • 00:11:02 response dot JSON and now if we have a
  • 00:11:06 look at the
  • 00:11:08 response we got back when using our
  • 00:11:11 level back-end or our API endpoint with
  • 00:11:13 postman let's have a look here you see
  • 00:11:16 we get back this javascript object where
  • 00:11:19 we then have a quotes property which
  • 00:11:21 actually holds the array of quotes and I
  • 00:11:23 just see we did delete it so we will
  • 00:11:25 have to create one to see it again but
  • 00:11:28 the issue or not the issue but the
  • 00:11:30 important thing to recognize is we're
  • 00:11:32 storing the quotes under a quotes
  • 00:11:35 property therefore here when we're
  • 00:11:37 extracting this and mapping it
  • 00:11:39 I should access dot quotes on the
  • 00:11:42 extracted body we're extracting the body
  • 00:11:44 with the JSON method but then again
  • 00:11:46 quotes to really get that array of
  • 00:11:49 quotes and return this and the map
  • 00:11:51 method so with that I'm getting all the
  • 00:11:54 quotes now it's time to go to the quotes
  • 00:11:58 component here where I loop through them
  • 00:12:01 and create individual quotes and somehow
  • 00:12:04 hook up this get quote or get quotes
  • 00:12:08 button so on get quotes was the method
  • 00:12:10 name I set up there so let's add this
  • 00:12:13 let's also inject our quote service so
  • 00:12:18 private quote service of type quote
  • 00:12:21 service here also add the import and
  • 00:12:25 also of course added to the providers
  • 00:12:27 array in the app module quote service to
  • 00:12:30 make sure it is available the angle to
  • 00:12:33 injector can create it and with this
  • 00:12:36 setup back into quotes component with
  • 00:12:39 the service injected in on get quotes
  • 00:12:42 which is fired when we click that button
  • 00:12:44 I want to reach out to my quote service
  • 00:12:48 get quotes and this of course is an
  • 00:12:50 observable so I'll subscribe to it and
  • 00:12:53 here I know I either get my array of
  • 00:12:56 quotes this is when we have a successful
  • 00:12:58 response and I'm mapping it so here
  • 00:13:02 quotes whoops this is just quote of
  • 00:13:06 course my blueprint here and then I want
  • 00:13:09 to use this array of quotes and we could
  • 00:13:11 either also log it to the console or
  • 00:13:13 simply set our quotes property up here
  • 00:13:18 equal to the quotes we're getting back
  • 00:13:21 and we could also of course get a
  • 00:13:23 response which is an error type response
  • 00:13:26 which our import here from a Tingler
  • 00:13:28 HTTP and well here I simply then want to
  • 00:13:32 lock this to the console so that we can
  • 00:13:35 investigate what's going wrong so
  • 00:13:38 omelette code quotes is hooked up in the
  • 00:13:40 best case we're fetching the quotes and
  • 00:13:42 populating our quotes property we're
  • 00:13:45 then looping through all those quotes
  • 00:13:47 and replicate the single quote component
  • 00:13:51 but there's one important thing missing
  • 00:13:53 we're not passing the quote to that
  • 00:13:55 single quote component in that quote
  • 00:13:59 component we have a quote property but
  • 00:14:02 this can't be set from outside so may
  • 00:14:04 let's make it settable by adding at
  • 00:14:07 input here at input in front of it
  • 00:14:10 import input from adding lock or now we
  • 00:14:13 can bind it from outside and now in the
  • 00:14:16 quotes component here in the template I
  • 00:14:18 can bind to quote with square brackets
  • 00:14:22 using property binding and I want to
  • 00:14:25 bind to quote I'm looping through here
  • 00:14:27 so now quote here between the square
  • 00:14:30 brackets refers to quote property in the
  • 00:14:33 quote component I'm sorry I know there
  • 00:14:35 are a lot of quotes and the shouldn't
  • 00:14:39 here and D quote here between quotation
  • 00:14:42 marks in my quotes components of plural
  • 00:14:45 refers to be quote in the loop so if
  • 00:14:48 that I'm looping for all the quotes and
  • 00:14:50 passed individual quotes a quote to the
  • 00:14:53 single quote component here and with all
  • 00:14:56 those quotes going on we should be able
  • 00:14:59 to now see that in action now since we
  • 00:15:02 deleted all quotes in the last video
  • 00:15:06 let me quickly create a new one by
  • 00:15:07 sending a post request with postman as
  • 00:15:10 shown in the last video to D slash quote
  • 00:15:14 API endpoint make sure to set the right
  • 00:15:17 headers here content type application
  • 00:15:20 jason and body raw here let's quickly
  • 00:15:25 create a new jason document content will
  • 00:15:29 be some quote so let's send it
  • 00:15:34 quote was created indeed so let's get it
  • 00:15:38 here we see it here now let's see it now
  • 00:15:41 running application well we don't even
  • 00:15:44 see a running application do we this is
  • 00:15:46 an issue kind of related to this issue
  • 00:15:49 with the routing where I needed to add
  • 00:15:51 module with providers I'm not sure if
  • 00:15:53 this will stay or will be fixed if it's
  • 00:15:56 a bug or a feature right now in the code
  • 00:16:00 service I need to be very explicit about
  • 00:16:02 what this get quotes method is returning
  • 00:16:05 and this of course is observable
  • 00:16:06 wrapping anything so you need to add the
  • 00:16:09 import to observable from rxjs and make
  • 00:16:12 sure to be explicit about what you're
  • 00:16:14 returning here this generally is a good
  • 00:16:16 practice but again since we are
  • 00:16:18 returning an observable here normally
  • 00:16:20 type scripture be able to infer this but
  • 00:16:23 I'll add it here with this save we
  • 00:16:25 should see that our application now
  • 00:16:27 loads correctly and now let's hit get
  • 00:16:30 quotes well I don't see any quotes let's
  • 00:16:34 open up the console and here we got an
  • 00:16:37 error that no access control allow
  • 00:16:40 origin is present what is that this is
  • 00:16:46 something which is a security feature in
  • 00:16:51 general it's called cross-origin
  • 00:16:53 resource sharing we're having two
  • 00:16:57 different servers talking to each other
  • 00:17:00 here our angler queue application here
  • 00:17:03 runs on localhost 4200 as you can
  • 00:17:06 clearly see and our back-end clearly
  • 00:17:10 runs on the lateral ng to view death
  • 00:17:12 domain which is a different server this
  • 00:17:15 is not the same it's both on localhost
  • 00:17:17 but localhost for have 4200 using port
  • 00:17:21 4200 actually it's a different domain
  • 00:17:23 then localhost whatever port dis uses
  • 00:17:27 behind the scenes so both runs locally
  • 00:17:29 kind of well this even runs in vagrant
  • 00:17:33 here so it's kind of different but even
  • 00:17:34 on the same machine a local host with a
  • 00:17:36 port is not the same as localhost with
  • 00:17:39 no port or some other port so two
  • 00:17:42 different domains and this is a typical
  • 00:17:44 problem you'll encounter in such
  • 00:17:47 application
  • 00:17:48 where your front end is served from a
  • 00:17:49 different server than your back end
  • 00:17:51 normally it's not allowed for both to
  • 00:17:54 communicate because it's kind of fishy
  • 00:17:55 if some other fronted at some other
  • 00:17:59 content wants to access your back-end
  • 00:18:01 but we're living in 2017 now and there
  • 00:18:06 this is absolutely normal because we
  • 00:18:07 have a lot of applications which simply
  • 00:18:09 expose some API endpoints for different
  • 00:18:12 apps to connect to them and therefore we
  • 00:18:14 can fix this and we will fix this in the
  • 00:18:17 next video because fixing this setting
  • 00:18:20 up the ability for our front-end app to
  • 00:18:23 XOR back it up when we have different
  • 00:18:25 servers is such a key thing that we
  • 00:18:28 definitely need a separate video for
  • 00:18:30 this as it's very interesting and
  • 00:18:32 something you will need in a lot of
  • 00:18:34 different and every use case is to so
  • 00:18:36 see you there bye