Now that we have an understanding of single-page applications,
we'll continue working on
our angular application that we have been working in the exercises so
far and develop it into
the single-page application using the support of the angular router module.
We have already included multiple components as part of
our angular application in the previous exercise and we have already
configured for our angular application to be able to route
between two different components.
Now, we will integrate more into our angular application and
develop it into the full-fledged angular application together with
the navigation among the various views
rendered by the various components of our application.
Continuing with our application as it stands now,
we have the home being rendered when you navigate to our application
right now and then the Home template has
been shown between the header and the footer and then when you go to the Menu,
the menu is being shown between the header and the footer in the view here.
Now, obviously, we need to integrate the other components that we
included into our angular application
to develop this as a full-fledged angular application.
In this exercise, we're going to integrate the ContactComponent,
we will update the template for the ContactComponent,
we will also update the template for the HomeComponent and take this
a step forward towards our single-page angular application.
Let's start out with the ContactComponent.
To get started, first copy the template for
the ContactComponent that I have given you in the exercise instructions and then
paste it into the contactcomponent.html file so that we will flush
out the actual view of our ContactComponent in a bit more detail here.
Now, you can see that I have cut and pasted the code for
the template file from the instructions into my ContactComponent.
We will complete the integration of
the ContactComponent in our application and then we'll look at
what the ContactComponent looks like and then come back
and quickly look at this code a little bit later.
Now, to integrate the ContactComponent into our angular application,
we need to include a path to the ContactComponent into our routes.
So, going to the routes.ts file right after the Menu,
I'm going to include another path for the ContactComponent I will use
the URL as contact us and
the corresponding component is ContactComponent here.
So, with this, we have now integrated our ContactComponent
into our application and let's save the changes to
this and then we will also need to update the header component and update
the a link in the header component to help us to navigate to the ContactComponent.
So, I'm just going to copy this from the menu a link in
my header component's toolbar there and then copy that into
the ContactComponent and then update it as contact us.
Let's save the changes to all the files and
then have a look at the resulting application.
Going to the application in our browser,
if we now navigate to the ContactComponent,
we can see that the details of the ContactComponent are displayed
here between the header and the footer as we expect.
So, inside the ContactComponent,
we have the Contact Us title
there and then some location information where I have displayed the address.
So, this is similar to the address that we
have in the footer so I'm not going to explain that in
detail then we have another part here where we include the Map of our Location.
We are not going to do that at the moment,
we're going to just leave it as blank and then also you see that I have
three buttons that I have included here for Call, Skype, and Email.
These three buttons are activated in our application
and I'm using the mat raised button to render these three buttons.
So, you can see that these buttons look different from
the other buttons that you've included in your application there.
So, this is a raised button component from our angular material there.
So, having seen the ContactComponent and
the fact that we are able to navigate to the ContactComponent.
Now, from the other components,
let's take a quick look at
the HTML code that we included for the template for our ContactComponent.
Going to contactcomponent.html, you'll see that we have
the title for this page included by using this div
here and the second div inside here with fxFlex
includes the location information and then this inside this location information,
I'm again defining another div which will allow me to
include multiple views into this other div here.
So, inside this, I'm defining
another div with effects layout column and effects layer row.
So, this is nested way of defining my CSS Flex views here.
So, inside this again,
I'm using a div Flex view with fxFlex 50 so it
occupies one half and then fxFlex offset 20 pixels.
So, this CSS view will be displaced to the right by 20 pixels so I
have some margin there and then we have
the address included here and then down below here,
you can see that inside another div,
I have an a tag with mat raised button associated with it.
This is what causes the raised buttons that we
have at the bottom of the Contact page there.
So, three of them here.
One for the telephone number.
One for the Skype and one for the email here and also note that I am making use of
the Font Awesome icons for each of them and then the
map of your location in another div here.
So, both these enclose inside this outer div which is enclosed again inside the div.
So, nested way of defining the flex layouts for our different parts here.
So, that's about it for the ContactComponent.
We have now integrated that into our single-page application.
Now, going to the DishService.
Now, in the DishService along with the getDishes method,
I'm going to introduce two more methods.
One method called getDish,
a specific dish and then I will identify the dish with an id specified here.
So, the id would
be and that would specify give me the dish with the id corresponding to this number.
So that will be one more method that I'm going to add
in and also add in another method called getFeaturedDish.
So, this featured dish will use
the featured property that we added
and then return the dish for which the feature is set to true.
So, that's the way you can select out one specific dish and then make it available.
Now, the reason why I have that featured flag is that when the feature is set to true,
that particular dish will be rendered on the HomeComponent.
Now, how do we select these dishes?
So, let's add in the code for this.
So, for the getDish,
I need to return something from the dishes constant that I already have there.
So, from the dishes constant,
I'm going to use the JavaScript's way of doing filtering of an array.
So, the filtering of an array will help me to select
out only those elements from the array that
match a particular criteria that will be specified
inside the filter here and then among them I will return only the first one.
Now, it so happens that when I specify an id,
it will select only one item but then that'll become an array.
So, from that array, I need to extract out that one element in that array.
So, that's why I'm using within braces zero there.
So, that will help me identify.
So, how do I filter my dishes?
So, for each dish in my list of dishes,
so this is where I'm going to use
another feature of typescript called as arrow functions.
The arrow function is a shorthand way of writing a function.
So, if you are used to writing functions,
instead of writing the function elaborately saying
function and then within brackets dish and so on,
I can simply write it in cases where the function is very simple,
it's very easy to write this as an arrow function here.
So, in here, I will specify saying dish id is equal to the id.
So, what I'm specifying here is filter the dishes array and extract out
only those items from the array for which the dish id.
So, each item here is being identified by this parameter dish here.
So, for which the dish id matches the
id that has been supplied as a parameter to the dish.
So, this way you will extract out that specific dish from
this array and then return that dish from this getDish method.
The arrow functions helped me to write code in a more simpler way.
If you don't like arrow functions
then you can write it in the more conventional way by saying,
"function dish", and then from this then you'll return dish.id triple equal to id,
so this will return a Boolean.
When the filter encounters a true inside here,
those elements from the dishes will be selected out into the array.
So, this is where your JavaScript knowledge comes to your advantage.
So, you need to know how a JavaScript filter
works to help you to understand how this is done.
Okay, now similarly for the featured dish,
I'm going to use a similar method for extracting from my dishes
array using a filter here but the filter that
I'm going to define here would be again an arrow function here.
You'll get used to arrow functions and then once you get used to them,
then you'll realize how simple they are too right.
So, in here the way for selecting me
is dish.featured property because this dish.feature is already a Boolean there.
So, that will help me to return the featured dish.
So, for whichever the dish,
the dish feature is true.
That particular dish will be filtered out from
the dishes array and then there will be only one day.
Anyway, you should make sure of that
so that you'll set featured only to true for one of those,
and then I use this because this filter will return a sub array from the dishes array,
so I need to select out that element.
There'll be one single element there at index zero.
So, I am using the index zero to select that element and return
that from the get featured dish method here.
So, that completes the update to the dish service.
To construct our home template,
we're going to feature on the home view a selected dish,
a selected current promotion by the restaurant,
and a selected corporate leader from the list of readers.
The corporate leader that is featured on the front page will
be part of your assignment that follows this particular lesson.
But we are going to now include,
we have a featured dish and the featured promotion on the front page.
So, which means that I need a promotion service which returns
the set of promotions that are being conducted by this particular restaurant.
So, let me add in a promotions service for my application.
So, to do that, in the shared folder,
I'm going to create a new file called promotion.ts.
In the promotion.ts, I will create a class,
class promotion and return this promotion here.
So, what does this promotion class contain?
It contains an id property,
then it contains the name for the promotion of the restaurant.
So for example, the promotion could be like weekend buffet.
Or 10% of every single day at
lunchtime and things like that can be featured on your restaurants front page there.
So, name then I will also include an image,
which is to be of the type string the image URL,
then label which will be a string.
Price also a string.
Now, the labor implies,
you don't see me using them at the moment,
we will bring them into usage in one of the later exercises featured Boolean.
So, you see the featured flag again appearing in the promotion also,
and then description string.
So, you see that the promotion structured is pretty much
similar to the dish structure that we have seen earlier.
So, this is the promotion class here.
Now, along with the promotion class,
I need to create another class that
exports the set of promotion say constant with promotions here.
So here, I'm going to import
the promotion class
from the promotion.ts file,
and then I would export a constant called promotion.
So, you see that I am using a structure very similar to the dishes here.
So, you begin to see that,
that structure that we used earlier for
the promotions for the dishes is also useful for declaring promotions.
If you have a different structure,
you will see that with leaders the structure will be a little bit
different for the JavaScript object here. The promotions.
Now, the details of a specific promotion I have given it in the instructions,
so I would suggest that you copy and paste it from
there instead of me typing the whole thing in here.
So, let me go ahead and copy and paste
that JavaScript object into this JavaScript object array here,
so there you go.
The promotion has just one single object at the moment.
In the future, we can add more.
At this point, I have only one so I just added it in there,
and I'm going to use that and that is the featured promotion for my restaurant there.
This is just promotion,
so let me update that promotions,
that's what I need.
So, I'm just going to save the changes to the promotion.ts file.
Next, I will create another service called promotion service.
So to do that, let's go to the command line at the command prompt type
ng generate surveys services/promotion.
So, the promotion service being created there.
So, now the PromotionService is up in place.
So, let's add in the features for the PromotionService.
So, going to the PromotionService,
you see that the PromotionService is now included in your services folder here,
so we need to prepare a PromotionService.
So, in the PromotionService,
I'm going to import
promotion from shared/promotion,
the promotion class, and also import
promotions from shared/promotions class there.
The constant promotions from there.
Now, just like we had for the dish service,
we need to create three methods inside the PromotionsService.
So, what I am going to do is to save myself the trouble,
I will go into the dish.service,
and then just copy these three,
and then paste it into my promotion service,
then just edit the code.
Okay, so from the promotion service,
I need to return getPromotions and
this is of the type promotion and then this will return PROMOTIONS,
and then get the second one would be promotion
which again receives the id of the promotion,
so I'm going to return
PROMOTIONS.filter promo.id is id.
Then getFeatured promotion.
So, you can see that the structure of the Promotionservice is very much similar to
the dishservice and this wouldn't be promotion type,
and this will return
PROMOTIONS.filter promo and this will be promo.featured and that's it.
My PromotionService is all ready.
Now, I am going to go into the home component, and prepare that,
so that in my home component,
I will display a featured dish and a featured promotion.
The featured/dish and featured/promotion will be displayed in
the home component using the angular material card component.
So, we need to first get the data into our home component,
so that's what we will do in the home components type script file there.
So, going to the home components type script file, home component.ts.
In here, I need to import the dish
from shared/dish and also the
corresponding dish.service from services/dish.service.
Okay, now I'm going to also do that same thing for promotions,
so I'm just going to copy that and paste it in here,
and then edit this one,
so this would be promotion,
this would be PromotionService,
and then promotion, and then this would be PromotionService.
So, with this, we have both the dish and
dish services and promotion service available for us,
within our home component.
Coming now to the constructor.
Lets now inject the two services here,
and make them available for our applications or dish service,
and the promotion service injected here.
So, with this, we have access to both the services.
So now within the ngOnInit method,
I'm going to fetch the two featured dishes.
So, I would say this.dishService.getFeaturedDish
and also promotion,
promotionService and getFeaturedPromotion.
Just to be complete,
let me declare the dish here as of
type Dish and the promotion as of type Promotion here.
So, that should clarify all the values that we are using inside here.
So, with this, we complete the update to our home components typescript file.
Let's now switch to the template file,
and then add in the two cards to display the featured dish and the featured promotion.
Now, for this, I have given you the code in the instructions.
So, I'm just going to copy that code and paste it in here.
You already know how to create cards,
so you would be able to easily follow the code that I paste here.
So, the home components template is also updated,
so you can see that it has two cards here.
For one, displaying the dish and the other one displaying the promotion here,
and enclosed inside a fxLayout div here.
So, let's save the changes and then take a quick look at our application.
After creating the promotion service,
we also need to include the promotion service in the AppModule,
and make it available for our application.
So, I'm going to go in here,
and then import
the promotion service in here.
Then, declared the promotion service
as one of the providers
in my AppModule.ts file here.
So, in the AppModule file,
I'm requiring both these,
and then saving changes.
Going to the browser,
you can now see that in the browser,
the home component now shows the two cards,
one for the featured dish and one for the featured promotion here.
So, you can see that the two cars are displayed here.
I can now navigate to the Menu page,
and then also to the Contact page.
The About page is still not there,
you're going to fill in the About page as part of your second assignment.
Taking a look at the same application on a smaller screen size,
so this is an iPhone 6 Plus screen.
Let's look at the home component and an iPhone 6 Plus screen.
You can see that featured dish and featured promotion on the homepage there.
Then, the menu that we have seen earlier,
and also the Contact page being displayed here.
So, you can see that now our single-page application is a lot more configured.
Except for the About,
which we will do in the second assignment.
One more minor change that you can do in your header components HTML file,
is that along with the router link directive,
the Angular Route are also supports one more a directive called routeLinkActive.
This allows us to apply some classes to the particular element here.
So, in this case,
if this link becomes active than whatever I specify here,
will be applied as a class to this particular item there.
So, I'm going to specify a class called active.
So here, I'm specifying routerLinkActive with active.
So, if I define a CSS class called active,
then the class will be applied to this link,
whenever this particular view is being shown on the applications page here.
I'm going to copy the same thing and apply it to all the remaining buttons,
where I have defined the router link already.
So, I'm going to apply the routerLinkActive class,
to the Home, the Menu and the Contact Us.
Now, this also means that I should define an active CSS class.
So, to do that, I'm going to go into the header components SESS file,
and then define an active class here,
so I will define the active class right there.
To define the active class,
I'm going to add in one more color variable here called background-moredark.
Then, the corresponding colour is 4527A0,
this is a darker version of this background dark color, 4527A0.
Then, for my active,
what I'm going to do is, from active class,
I will let the class define a background,
set the background of
that element to the background-moredark color.
So, when that particular view is selected and shown in the page,
then this active class will be applied to
that particular A tag
there by the router link active directive that we have applied here.
Now, what change does this cause on our webpage.
Now, going to our webpage,
we will see what this introduces on our webpage.
Going to our application,
you now see that when we are in
the home view in the home component being displayed here, its corresponding view.
Then, the Home button here has a different background color that is
applied because the active class has been added in because we
define the routerLinkActive to active here.
So, that class is applied.
Similarly, when you select the menu,
then you see that the menu is highlighted in the header,
and the menus view is shown here,
and similarly for the content.
Now, this enables us to see at a glance on which pay particular view VR,
in our single page application.
So, this is an additional little bit offer enhancement to the UI,
that enables us to see some interesting features.
Although, it doesn't add much to the functionality of the application,
but just add some little feature that will be a useful addition to your application.
So, with this, we complete this exercise.
In this exercise, we have worked to integrate
the contact component into our single page application.
We also designed a couple of cards that we included into the home component,
and added in a few new features to our application.
This is a good time for you to save the changes to your Git repository with the message,
Single Page Application Part 1.