[SOLVED] WEB422 Assignment 4

30.00 $

Category:
Click Category Button to View Your Next Assignment | Homework

You will receive the following solution file(s) instantly after successful payment:

zip file icon Assignment-4-wegqji.zip (8125.9 KB)
Assignment Instructions Updated Recently? Submit Below and we will provide new Solution!
Submit New Instructions
πŸ”’ Securely Powered by:
Secure Checkout
5/5 - (1 vote)

For this assignment, we will be working with a professionally designed Bootstrap 4 β€œBlog” theme from https://bootstrapious.com/. (Important Note: we are using the β€œfree” version of this template, which means we must keep the footer link back to Bootstrapious, ie: β€œTemplate By Bootstrapious” intact in the footer)

The goal of this assignment is to use our knowledge of Angular to begin development and prototyping of a useable and scalable Blogging system User Interface (UI).Β  We must use the provided HTML & CSS to help guide our design decisions and develop custom components to work with and display data.Β  We will not have any β€œlive” data for this blog, but we will have some test data that we can use to ensure that all of the components function properly.

Β 

Specification:

Step 1: Creating an Angular App & Downloading the Files

To begin this project we must create a new Angular app using the @angular/cli command line tool: β€œng”.Β  If you do not have it installed yet, you can pull it from npm using the command:

Β 

npm install -g @angular/cli

Β 

Once the Angular CLI has been installed, you should be able to kickstart a new Angular application with the following command (Note: The options here enable routing, skip testing and skip the initialization of a β€œgit” repository, respectfully)

Β 

ng new web422-a4 –routing -S -g

Β 

With our app in place, we must now download the template files.Β  You will not have to download anything directly from β€œbootstrapious” – instead, we have provided you with the main files that you will need here:

Β 

https://ict.senecacollege.ca/~patrick.crawford/shared/winter–2020/web422/A4/static.zip

Β 

Step 2: Static Content & Main β€œView” Components

Before we start adding the HTML & CSS, we have to make a few updates to our index.html file, ie: Add the following HTML just before the closing <head> tag to the β€œindex.html” file.Β  The paths won’t make any sense yet, but we’ll fix that in the next step:

Β 

<!– Bootstrap CSS–>

<link rel=”stylesheet” href=”/assets/vendor/bootstrap/css/bootstrap.min.css”>

<!– Font Awesome CSS–>

<link rel=”stylesheet” href=”/assets/vendor/font-awesome/css/font-awesome.min.css”> <!– Custom icon font–>

<link rel=”stylesheet” href=”/assets/css/fontastic.css”>

<!– Google fonts – Open Sans–>

<link rel=”stylesheet” href=”https://fonts.googleapis.com/css?family=Open+Sans:300,400,700β€³>

Β 

<!– theme stylesheet–>

<link rel=”stylesheet” href=”/assets/css/style.default.css” id=”theme-stylesheet”>

<!– Custom stylesheet – for your changes–>

<link rel=”stylesheet” href=”/assets/css/custom.css”> <!– Favicon–>

<link rel=”shortcut icon” href=”/assets/img/favicon.ico”>

<!– Tweaks for older IEs–><!–[if lt IE 9]>

Β Β Β  <script src=”https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js”></script>

Β Β Β  <script src=”https://oss.maxcdn.com/respond/1.4.2/respond.min.js”></script><![endif]–>

Β 

Next, we must copy the following folders (from our download in Step 1) into the β€œsrc/assets” folder within our newly created Angular application:

Β 

  • css
  • vendor
  • img
  • fonts

Β 

Finally, wipe out all of the content from app.component.html and replace it with <p>App Works!</p> (just to render something for the time being).

Β 

Β 

Creating new β€œview” Components

Β 

Now that all of our styles are in place, we must create the primary components that will be rendered using client side routing.Β  These can be thought of as the β€œview” components.Β  Within most of these components, we will be creating smaller components.Β  However, before we do that, let’s get the boilerplate code for each β€œview” added in its own component:

Β 

For the next steps, use the Angular CLI (ng) to create the following components with boilerplate templates from the files provided (step 1)

Β 

Β 

HeaderComponent (header.component.ts)

Β 

  • Once you have created this component, copy the contents of the file β€œhtml” into the contents of β€œheader.component.html” (replacing the automatically-generated paragraph element) and save the file.
  • If you wish to test it at this time, you can add the <app-header></app-header> component to the component.html file

Β 

FooterComponent (footer.component.ts)

Β 

  • Once you have created this component, copy the contents of the file β€œhtml” into the contents of β€œfooter.component.html” (replacing the automatically-generated paragraph element) and save the file.
  • If you wish to test it at this time, you can add the <app-footer></app-footer> component to the component.html file

Β 

HomeComponent (home.component.ts)

Β 

  • Once you have created this component, copy the contents of the file β€œhtml” into the contents of β€œhome.component.html” (replacing the automatically-generated paragraph element) and save the file.
  • If you wish to test it at this time, you can add the <app-home></app-home> component to the component.html file (ideally between the header and footer)

Β 

BlogComponent (blog.component.ts)

Β 

  • Once you have created this component, copy the contents of the file β€œhtml” into the contents of β€œblog.component.html” (replacing the automatically-generated paragraph element) and save the file.
  • If you wish to test it at this time, you can add the <app-blog></app-blog> component to the component.html file (ideally between the header and footer – you may want to comment out <apphome></app-home> if it was previously added)

Β 

PostComponent (post.component.ts)

Β 

  • Once you have created this component, copy the contents of the file β€œhtml” into the contents of β€œpost.component.html” (replacing the automatically-generated paragraph element) and save the file.
  • If you wish to test it at this time, you can add the <app-post></app-post> component to the component.html file (ideally between the header and footer– you may want to comment out <appblog></app-blog> if it was previously added)

Β 

PageNotFoundComponent (page-not-found.component.ts)

Β 

  • You are free to put whatever you like in this template – it’s the β€œ404” view for our application

Step 3: Main Route Configuration

Β 

Now that our main components are in place, it’s a good idea to get β€œrouting” up and running to make it easier to test and develop each individual view.Β  To begin, configure the following routes in yourΒ  app-routing.module.ts file by adding the configurations to the Routes array:

Β 

  • Path: β€œhome” – Shows the HomeComponent
  • Path: β€œblog” – Shows the BlogComponent
  • Path: β€œpost” – Shows the PostComponent
  • Path: β€œβ€ – Redirects to the β€œ/home” Route
  • No Route Found – Shows the PageNotFoundComponent

Β 

Once this is complete, place the β€œrouter outlet” component (<router-outlet></router-outlet>) between the <app-header></app-header> and <app-footer></app-footer> components in your app.component.html file.

Β 

As a final task before we start configuring our individual β€œviews”, let’s make the β€œheader” work with our Angular Routing components:

Β 

  • Replace all 3 href properties with routerLink – this will ensure that whenever they are clicked, it will use our Angular routing instead of the default browser routing.
  • Next, to ensure that our menu items are correctly highlighted, add the following β€œdirective” to the same 3 anchor elements:

o routerLinkActive=”active”

Β 

Β 

Step 4: Mock β€œBlog” Data

Before we start dividing our views into reusable components (you probably have spotted all of the β€œwidgets” in the side bar – these are perfect candidates), let’s add a few fake blog posts.

Β 

Since we’re using typescript, it makes sense for our data to be β€œtyped” – ie: we must have a β€œclass” to define the β€œshape” of each post.Β  To achieve this, add the following 2 files / content

Β 

Comment.ts

Β 

export class Comment{

_id: stringΒ Β Β Β  author: string;Β Β Β Β  comment: string;

date: string;

}

Β 

BlogPost.ts

Β 

import { Comment } from β€œ./Comment”;

Β 

export class BlogPost{

_id: string

title: string;Β Β Β Β  postDate: string;Β Β Β Β  featuredImage: string;

post: string;

postedBy: string;

comments: Array<Comment>;

category: string;Β Β Β Β  tags: Array<string>;Β Β Β Β  isPrivate: Boolean;

views: number;

}

Β 

Next, we must copy the blogData.json file (from our files included with the download in step 1) and place it within the β€œapp” folder.Β  This will serve as our sample data for the blog.

Β 

Unfortunately, if we want to actually β€œimport” this json file in any of our components, we must add a couple of

β€œcompiler options” to our typescript configuration, ie: add the following two properties to the

β€œcompilerOptions” property in the β€œtsconfig.base.json” file

Β 

  • β€œresolveJsonModule”: true
  • β€œesModuleInterop”: true

Β 

Now, if we want to ever pull in the data, we can add the following β€œimport” lines in our component files:

Β 

import blogData from β€˜../blogData.json’; import { BlogPost } from β€˜../BlogPost’;

Β 

In fact, since our β€œBlogComponent” will need the blog data, let’s proceed to add the above two β€œimport” lines to the top of the blog.component.ts file now.

Β 

Inside the BlogComponent class, add the following property declaration:

Β 

blogPosts: Array<BlogPost> = blogData;

Β 

This will ensure that our data is loaded as β€œblogPosts” before we start the next part of the assignment (in the future, this would come from a service which accesses a WEB API endpoint for data).

Β 

Β 

Step 5: β€œBlog” view components

Β 

If you open your app to the β€œblog” route, you will notice that we have quite a few β€œcontainers” in the UI that manage data.Β  In the next part of this assignment, we will build out components for these containers PostCardComponent

Β 

Β 

Β 

This component will be responsible for rendering the above chunk of UI (Hint: all the code inside <div class=”post col-xl-6β€³>…</div>, so use that as your template starting point).

Β 

To get started, create the component using the ng g c (ng generate component) command, then proceed to implement the component according to the following specifications:

Β 

  • It must receive a single property post. The type of this property will be BlogPost (therefore, { BlogPost } must be imported from β€˜../BlogPost’ and the @Input() decorator must also be used.Β  Do not forget to import β€œInput” from @angular/core
  • It must be rendered using the class property: β€œclass=”post col-xl-6”, ie: β€œ<app-post-card class=”post col-xl-6β€³>”
  • Its β€œpost-thumbnail” element must show the post’s β€œfeaturedImage”
  • Its β€œdate meta-last” element must show the post’s β€œpostDate”
  • Its β€œcateogory” element must show the post’s β€œcategory”
  • Its β€œ<h3 class=”h4”> element must show the post’s β€œtitle”
  • Its ” <p class=”text-muted”> element must be changed to a <div> element instead (ie: β€œ<div class=”textmuted”>…</div>”. Also its β€œinnerHtml” property must be set to the post’s β€œpost”
  • Its β€œavatar” image must be changed to β€œ/assets/img/user.svg”
  • Its β€œtitle” element must show the post’s β€œpostedBy”
  • Its β€œdate” element (next to the clock) must show the post’s β€œpostDate”
  • Its β€œmeta-last” element must show the number of comments, ie comments.length

Β 

Once this is done, use the new β€œapp-post-card” in place of the existing elements in the β€œblog.component.html” template.Β  You should be able to show one app-post-card per β€œpost” in the β€œblogPosts” array using *ngFor.

Β 

Using our sample data, your β€œblog” page should now look like the below screenshot:

Β 

Β 

Β 

SearchWidgetComponent

Β 

Β 

Β 

This component simply renders the β€œwidget-search” element, so use that as your template starting point.

Β 

To get started, create the component using the ng g c (ng generate component) command.Β  We will use this to render the template only – we not be implementing any logic at this time.

Β 

Β 

LatestPostsComponent

Β 

Β 

Β 

This component will be responsible for rendering the above chunk of UI (Hint: this is the <div class=”widget latest-posts”> element, so use that as your template starting point).

Β 

To get started, create the component using the ng g c (ng generate component) command, then proceed to implement the component according to the following specifications:

Β 

  • It must receive a single property posts. The type of this property will be Array<BlogPost> (therefore,

{ BlogPost } must be imported from β€˜../BlogPost’ and the @Input() decorator must also be used.Β  Do not forget to import β€œInput” from @angular/core

  • Inside the template, you will notice three β€œitem” elements, each nested inside an β€œ<a href=”#”>” element. The idea is that we must render one β€œitem” link for every β€œpost” in the β€œposts” array according to the following:
    • Its β€œimage” element must show the post’s β€œfeaturedImage”
    • Its β€œtitle” element must show the post’s β€œtitle” o Its β€œviews” element must show the post’s β€œviews”
    • Its β€œcomments” element must show the number of comments, ie comments.length

Note: When you include the component, you can limit the number of β€œblogPosts” that you provide to the component using the code:

Β 

<app-latest-posts [posts]=”blogPosts.slice(0,3)”></app-latest-posts>

Β 

When complete, your component should look like:

Β 

Β 

Β 

Β 

Β 

Β 

Β 

Β 

Β 

Β 

Β 

Β 

Β 

Β 

CategoriesComponent

Β 

Β 

Β 

This component will be responsible for rendering the above chunk of UI (Hint: this is the <div class=”widget categories”> element, so use that as your template starting point).

Β 

To get started, create the component using the ng g c (ng generate component) command, then proceed to implement the component according to the following specifications:

Β 

  • In the future, this component would have to worry about fetching the category data on its own. In the meantime, hardcode the following array as the component’s single property:

Β 

categories: Array<any> = [Β Β  {cat: β€œCrime”, num: 2},

{cat: β€œComedy”, num: 1},

{cat: β€œMusical”, num: 1},

{cat: β€œAdventure”, num: 2},

{cat: β€œDrama”, num: 2},

{cat: β€œAction”, num: 2},

{cat: β€œDocumentary”, num: 1},

{cat: β€œThriller”, num: 1}

];

Β 

  • In the template, you will notice that <div class=”item d-flex justify-content-between”>…</div> is repeated once per category. We will use our β€œcategories” array to accomplish the same output, ie: looping through the array and outputting one β€œitem” per element.

Β 

Β 

Β 

Β 

Β 

Β 

Β 

When complete, your component should look like:

Β 

Β 

Β 

Β 

TagsComponent

Β 

Β 

Β 

The TagsComponent functions very much like the CategoriesComponent in that it doesn’t accept any props and (for now) we will hardcode the existing tags into a β€œtags” array, ie:

Β 

tags: Array<string> =[

β€œ#funny”,

β€œ#dramatic”,

β€œ#rental”,

β€œ#seeagain”,

β€œ#spooky”,

β€œ#worththecost”,

β€œ#lovedIt”,

β€œ#scary”,

β€œ#silly”,

β€œ#good4kidz”

];

In the template, you will notice that <li class=”list-inline-item”>…</li> is repeated once per category.Β  We will use our β€œtag” array to accomplish the same output, ie: looping through the array and outputting one β€œlistinline-item” per element.

Β 

When complete, your component should look like:

Β 

Β 

Β 

Step 6: β€œPost” view components

Now that we have completed all of the β€œBlog” view components, we can move on to the β€œPost” view components.Β  The good news here is that that we can reuse most of the components from the β€œBlog” view

Β 

To get started, we will follow along with the same procedure as the β€œBlog” component, ie adding in the β€œblogPosts” array:

Β 

First, add the following β€œimport” lines in our post.component.ts file:

Β 

import blogData from β€˜../blogData.json’; import { BlogPost } from β€˜../BlogPost’;

Β 

Next, inside the PostComponent class, add the following property declaration:

Β 

blogPosts: Array<BlogPost> = blogData;

Β 

This will ensure that our data is loaded as β€œblogPosts” (once again – in the future, this would come from a service which accesses a WEB API endpoint for data).

Β 

Β 

Reusing the <aside> from blog.component.html

Β 

If you take a look at your completed blog.component.html, you should notice that your <aside> element is now much smaller than it used to be, ie:

Β 

<aside class=”col-lg-4β€³>

<!– Widget [Search Bar Widget]–>

<app-search-widget></app-search-widget>

<!– Widget [Latest Posts Widget] –>

<app-latest-posts [posts]=”blogPosts.slice(0,3)”></app-latest-posts>

<!– Widget [Categories Widget]–>

<app-categories></app-categories>

<!– Widget [Tags Cloud Widget]–>

<app-tags></app-tags>

</aside>

Β 

You will also notice that we have the exact same <aside> element in our post.component.html file (starting at line 100).Β  For this next step, simply copy your full <aside> element from your blog.component.html and paste it in place of the existing <aside> within your post.component.html file!

Β 

Β 

PostDataComponent (The last one!)

Β 

This Final Component is basically the entire β€œpost single” div from the sample html, ie: β€œ<div class=”postsingle”>…</div>” (everything from line 6 to line 94 inclusive).Β  So, to get started wiring up this component, simply cut all of that HTML including the <div class=”post-single”>…</div> container element, and paste it into your post-data.component.html.Β  Then, in its place add back:

Β 

<app-post-data [post]=”blogPosts[0]”></app-post-data>

Β 

Note: We will simply be hard-coding the first blog post for now.

Β 

Next, once your html is in the right place (post-data.component.html) we can start working with the template according to the following specifications:

Β 

  • It must receive a single property post. The type of this property will be BlogPost (therefore, { BlogPost } must be imported from β€˜../BlogPost’ and the @Input() decorator must also be used.Β  Do not forget to import β€œInput” from @angular/core
  • The β€œpost-thumbnail” must show the post’s β€œfeaturedImage”
  • The β€œcategory” must show the post’s β€œcategory”
  • The <h1>…</h1> element must show the post’s β€œtitle”
  • The β€œavatar” must be changed to show β€œ/assets/img/user.svg”
  • The β€œtitle” (directly beneath avatar) must show the post’s β€œpostedBy”
  • The β€œdate” element (next to the clock) must show the post’s β€œpostDate”
  • The β€œviews” element (next to the eye) must show the post’s β€œviews”
  • The β€œcomments” element must show the number of comments, ie comments.length
  • The β€œpost-body” innerHTML property must be set to the post’s β€œpost”
  • The β€œpost-tags” must show one β€œ<a href=”#” class=”tag”>…</a> element for every tag in the post’s β€œtags” array such that the content of the <a> shows the value of a tag used in the post
  • The β€œno-of-comments” must show the number of comments, ie comments.length

The last piece of this component implementation is the β€œcomments” list.Β  To complete this, we must iterate over the β€œcomments” array and display a <div class=”comment”>…</div>” for every comment in the array.

This will involve updating the following β€œcomment” related elements:

Β 

  • The β€œtitle” should show the current comment’s β€œauthor”
  • The β€œdata” should show the current comment’s β€œdate”
  • The β€œcomment body” innerHTML property must be set to the current comment’s β€œcomment” Step 7:Updating Links and Testing

Β 

You will notice that there are a few things that are missing from our solution. Most notably the out of date, static blog posts on the Home page and in the footer.Β  If you require additional practice with components please feel free to use the knowledge gained from updating the β€œBlog” and β€œPost” views to refactor these views as well.

Β 

Also, you will notice that there’s a lot of β€œhref” links still in the solution.Β  Unless the app requires the user to navigate away (ie: heading to twitter, etc.) then β€œhref” should be replaced with β€œrouterLink”, ie:

Β 

  • href=”#” should be replaced with routerLink
  • href=”post.html” should be replaced with routerLink=”/post”

Β 

Once this is complete, you should be ready to submit.Β  However have a look at the full-page screenshots of the app and compare your results with what you see.Β  Everyone is using the data, so it should look identical (unless you added some additional styling).

Β 

Β 

1 file Β· 7.9 MB

  • Assignment-4-wegqji.zip 7.9 MB