Learning Angular 5

I wrote an app using Angular 5 that does many of the basic features in Angular. The backend uses Node.js, Express and MySQL.

Introduction

My new years resolution for 2018 is to get a lot better at finnish. So I wanted an app to help me practice words and phrases repeatedly if necessary. I had already written a similar app that I had barely used in 2016. But now I wanted to update the app and at the same time learn Angular 5!

The app's source code can be found here: github.com/saaratrix/glossarytraining. It uses many of the basic features of Angular such as components, modules, routes and child routes. Here's a nice cheat sheet for features in Angular: angular.io/guide/cheatsheet. I'm using Less for CSS and the backend is written using Express to handle communicating with the MySQL database.

The app can be tested here: saaratrix.github.io/glossarytraining/dist/

Learning Angular

To learn Angular I mainly used 2 resources.
1. angular.io/ - Which is Angular's own website.
2. github.com/gothinkster/angular-realworld-example-app - Which I used as a guide on how to structure the app and other things such as how the routing was done.

Any issues I came across I either used angular.io or searched for solution.

Creating the app

To create the Angular app I followed the guide here: angular.io/guide/quickstart. The guide doesn't mention how to create an app using Less or Sass. Which you do by doing the following:

ng new my-app --style=less

Since I followed the angular.io guide I had to edit the .angular-cli.json file to add Less. I edited 2 properties from CSS to Less

            
"styles": [
    "styles.less"
],
"defaults": {
    "styleExt": "less",
    "component": {
    }
}
            
        

Lessons learned

When making the app I took notes of issues I had and how to solve them. This is what I learned!

Add modules of what is used to the *.module.ts file

This one is intuitive when you've learned the basics of Angular but as I started I got errors about using HttpClient. Which was solved by adding the HttpClientModule to the /shared/shared.module.ts file.

The module needs to be added to the *.module.ts file that does the declaration for the component using the model. For example for my admin view I had to add the FormsModule in the admin.module.ts. I could not add it in the app.module.ts or the shared.module.ts. It threw an error about ngModel directive until I added it to the admin.module.ts

Exporting a component

If component A wants to use component B and component B is declared in a different module. Then the other module needs to export component B so that component A can use it. Otherwise it throws an error about the @Input() parameters.

Example is my home component wants to use the quiz selection component.
Then the quiz module needs to export the quiz selection component.
And the home module needs to import the quiz module.

Creating services

When you're creating a service the service needs to be added to the providers array of the module exporting the service. Example here: shared module.

Detect changes in array

When passing an array to a component and the array is changed outside the component with for example array.push() then the component doesn't know that the array has changed without adding an IterableDiffers.
Example of IterableDiffers being used: phrases selection component.
The component is being used here: phrases quiz selection component.

Getting HTML element in component

You can get a reference to a HTML element by using @ViewChild("id") element: ElementRef for <div #id></div>
Example of @ViewChild("questionInput") being used: quiz text question component.
The element that's referenced in the example looks like this: <input #questionInput >

CSS Grid is nice!

It was my first time using CSS Grid and it's very nice to use. I used this tutorial to learn it: css-tricks.com/snippets/css/complete-guide-grid
Below is the whole CSS to make it into a 3 column grid that works for dynamic heights.

            
.questions-list {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    grid-gap: 8px;
}
            
        

As demonstrated it's very simple to use! An added bonus is that it also shows up in chrome when using inspect element with debugging tools.

Mistake when using Less

When using CanJS I've always encapsulated the component CSS with the components tag. CanJS is another framework that uses reusable components to create a web app. So encapsulating was a habit to make sure the CSS is properly scoped. This however is not how it works in Angular because it does it for you automatically. As a workaround until properly fixed I had to import each component's style file into the global styles.less file.

Here's an example of what I did wrong when I encapsulated the CSS for the <app-admin> component.

            
/* This didn't work without my @import workaround! */
app-admin {
    nav {
        margin-bottom: 15px;
    }
}
            
        

Correct way is to just omit the app-admin part and leave it like this:

            
/*
    This works perfectly because Angular handles the encapsulating for you automatically!
    Angular transforms the nav into nav[_ngcontent-c6] which makes sure the CSS is only for the navs of _ngcontent-c6 component.
*/
nav {
    margin-bottom: 15px;
}
            
        

The express backend

The Express app is based off the template here: github.com/designcourse/mean4plus. Which was to make sure it worked with Angular.
The API routes entry point is in the file /server/routes.ts
The backend uses MySQL npm package to communicate with the database. I wrote a generic query function to always return a promise to use for async/await.
The generic query is demonstrated in the /server/handlers/BaseHandler.ts
The server also has its own tsconfig.json which is compiled before launching server using the start-server script in package.json.

Conclusion

I like Angular and it's a powerful tool building web applications. That's true for many frameworks though :)
I'll be continue working on the glossary training app and the next feature to implement is verb training, I am, you are, it is ...
Hopefully next year I'll be speaking fluent finnish!

1 comment:

  1. Excellent article. Very interesting to read. I really love to read such a nice article. Thanks! keep rocking AngularJS Online Course

    ReplyDelete