DEV Community

Espoir Murhabazi
Espoir Murhabazi

Posted on

My first steps with Angular

I liked to think of myself as a backend engineer, but I was sometimes required (even forced) to engage in frontend development. UI, UX and frontend design & development was my weakness, and it was not something I was fond of one bit.

But this changed for me. It happened during one of my "forced" UI engagements. I decided to use a frontend framework, and to my surprise, I ended up liking it.

About three months ago, I started playing around with ReactJS. I did this for a couple of days and enjoyed what I was seeing. I, however, did not like that ReactJS was not a full framework. However, there were great takeaways though from playing around with it. I got to learn about state management with Redux and gained more general frontend development knowledge.

About 2 weeks ago, during a sprint planning session for an in-house application I have been working on with my team, I was assigned a frontend related task. The product frontend was using Angular which meant I had to grasp Angular in order to complete this task. I did what I needed to do to level up my skills to take on the task.
Fortunately, I had most of the necessary tools available to me to do this.

In this post, I will walk through how I solved the problem. This entails setting up Angular from scratch, understanding the building blocks of an Angular application. I will also share what I have liked so far, and what I believe my next steps towards learning Angular are.

Setting Up

Most tutorials I have come across online related to Angular tend to use the Angular CLI to create and setup projects. I find that many new learners don't really understand what is happening under the hood.

As a person who likes to thoroughly grasp the technologies I work with, I tend to enjoy building applications scratch. Doing this means I clearly understand what goes on under the hood. I am then able to fully understand anything I build, and easily fix any issues/bugs that come up.

This tutorial helped me set up a simple project from the ground up, and build my first "Hello, world!" application. It is a great place to start for any Angular newbie.

Lessons learned after setting up Angular

I learned that :

  • Setting up Angular from scratch it's NOT a complicated process besides the optimization part which I decided to skip for the first time because it seems to add some complications.

  • I got to know that Angular uses TypeScript - A programming language created, developed and maintained by Microsoft. I like very much that it is a strongly typed language - similar to Java. Java was my first love. This made learning and writing TypeScript an enjoyable experience.

  • Since Angular uses typescript when setting Webpack we need to convert it into javascript code which can be understood by modern browsers.
    This is done in a file called tsconfig.json
    The simplest version of that file looks like this

{
    "compilerOptions": {
        "experimentalDecorators": true,
        "lib": [
            "dom",
            "esnext"
        ]
    }
}

Enter fullscreen mode Exit fullscreen mode

The experimentalDecorators option is responsible for properly processing decorator annotations (@Component and @NgModule). lib specifies the libraries used in our application and dependencies.

  • To compile code, Webpack need just some simple setup
    • The input directory: where to look for the code to compile
    • The output directory: where to put the compiled code by default it goes under the dist folder
    • resolve: specify which files extensions should be compiled for this case it compile all files with .ts and .js extensions.
    • A bunch of plugins to do the work:
      • An Html plugin which converts HTML code
      • script ext Html plugin which enhances html-webpack functionality with different deployment options for your scripts such as async and differs
      • copy plugin which static files from the src file to the dist folder
      • Angular compiler plugin which is in charge of the compilation of all angular code using the tsconfig.js and the entry module for our application.

After setting up I end up having a webpack.config.js file which looks like this :

const HtmlWebpackPlugin = require("html-webpack-plugin");
const CopyWebpackPlugin = require("copy-webpack-plugin");
const ScriptExtPlugin = require("script-ext-html-webpack-plugin");
const { AngularCompilerPlugin } = require("@ngtools/webpack");

module.exports = function() {
  return {
    mode: "development",
    entry: "./src/main.ts",
    output: {
      path: __dirname + "/dist",
      filename: "app.js"
    },
    resolve: { extensions: [".ts", ".js"] },
    module: { rules: [{ test: /\.ts$/, loader: "@ngtools/webpack" }] },
    plugins: [
      new CopyWebpackPlugin([{ from: "src/assets", to: "assets" }]),
      new HtmlWebpackPlugin({
        template: "./index.html",
        output: __dirname + "/dist",
        inject: "head"
      }),
      new ScriptExtPlugin({
        defaultAttribute: "defer"
      }),
      new AngularCompilerPlugin({
        tsConfigPath: "./tsconfig.json",
        entryModule: "./src/app/app.module#AppModule",
        sourceMap: true
      })
    ]
  };
};

Enter fullscreen mode Exit fullscreen mode

With that setup, I added the following line in my package.json file to build and run my application.

"scripts": {
    "build": "webpack",
    "start": "webpack-dev-server --port=4201"
  },
Enter fullscreen mode Exit fullscreen mode

I was a milestone for me to be able to setup Angular from scratch and to be able to complete my first tutorial and to see a Hello word in angular.
I decided to find another tutorial to learn how angular application works.

You can find the full project where I set up angular here

The building blocks of an angular application

I used this tutorial to build a CRUD application of angular and to get exposed to the building blocks of an angular application.

In the following section, I will talk about services, resolvers, components, routers, modules, and models in Angular. They are in my opinion the buildings blocks of an Angular application.

That tutorial helps me to build an application which fetches data from an apis and display them in an HTML component.

It also explains how angular applications are structured and how it uses single responsibility principles.

Components and templates :

Components can be found in many front end framework, a component is the most basic building block for a UI application. Anything can be a component from a simple Html button to a full nested div which display a full page.
It is a best practice to keep each part of a web page controlled by a single component to force the single responsibility principle
Components are reusable and can be combined.

In angular, a component is created by using the @component decorator which take properties like :

  • the template or the Html page to use
  • the Html selector for the component
  • the stylesheet to use

Templates are HTML pages which display data form the components. Sometimes they can have customs Angulars tags.

Here is how my first component looks like.


import {Component, OnInit} from '@angular/core'
import {ActivatedRoute} from '@angular/router'
import {CategoryModel}  from '../../models/category.model'

@Component(
    {
    selector : 'categories',
    styleUrls : ['../categories/categories.component.scss'],
    templateUrl: '../categories/categories.component.html'
    }
)

export class CategoriesComponent implements OnInit{
 categories : CategoryModel[];
 constructor(private route : ActivatedRoute){}
 ngOnInit() : void {
 this.route.data.subscribe(routeData =>{
     let data = routeData['data'];
     if (data){
         this.categories = data.categories
     }
 })
 }
}
Enter fullscreen mode Exit fullscreen mode

Services :

Almost anything can be a service, any value, function, or feature that your application needs. A service is typically a class with a narrow, well-defined purpose. It should do something specific and do it well. The main purpose of Angular Services is sharing resources across components.

In the project, I have a service which makes an Http call and returns data to be displayed by a component.

The component consumes the data provided by the service.

When building service it's highly recommended as a best practice to keep one service for one task: separation of concerns.

My first service which makes a request to a dummy API looks like this.


import { Injectable } from '@angular/core';
import { Http } from '@angular/http';
import { CategoryModel } from "../models/category.model";

@Injectable()
export class CategoriesService {

    constructor(private http: Http) { }

    getCategories(): Promise<CategoryModel[]> {
        return this.http.get("./assets/categories.json")
            .toPromise()
            .then(res => res.json() as CategoryModel[])
    }

    getCategoryBySlug(slug: string) {
        return this.getCategories()
            .then(categories => {
                return categories.find((category) => {
                    return category.slug == slug;
                });
            })
    }
}
Enter fullscreen mode Exit fullscreen mode

Resolver:

A resolver is a class which helps to pre-fetch the component's data before the route is activated.
Using a resolver is a very good practice to make sure that all necessary data is ready for our components to use and avoid displaying a blank component while waiting for the data.

For example in we use a CategoriesResolver to fetch the list of categories. Once the categories are ready, we activate the route. Please note that if the resolve Observable does not complete, the navigation will not continue.

import { Injectable } from '@angular/core';
import { Resolve } from "@angular/router";
import { CategoriesService } from "../services/category.services";

@Injectable()
export class CategoriesResolver implements Resolve<any> {

    constructor(private categoriesService: CategoriesService) { }

    resolve() {
        return new Promise((resolve, reject) => {


            //get categories from local json file
            this.categoriesService.getCategories()
                .then(
                    categories => {
                        return resolve({
                            categories: categories,
                        });
                    },
                    err => {
                        return resolve(null);
                    }
                )
        });
    }
}
Enter fullscreen mode Exit fullscreen mode

Route:

Routes gives directions in our applications.
They are built with URLs, it tells the application when a URL is hit which component we should render and which data to display;


import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import {CategoriesComponent} from '../app/components/categories/categories.component'
import {CategoriesResolver} from '../app/resolvers/category.resolver'

const routes: Routes = [{
  path: '',
  component: CategoriesComponent,
  resolve: {
    data: CategoriesResolver
  }
}];

@NgModule({
  imports: [
    RouterModule.forRoot(routes,
      { useHash: false }
    )
  ],
  exports: [RouterModule]
})

Enter fullscreen mode Exit fullscreen mode

Models:

Models are the representation of the data used by our application. It can help for example to know which data we are expecting as response from an Http request.

export class CategoryModel {
    slug: string;
    title: string;
    image: string;
    description: string;
    tags: Array<Object>;
}

Enter fullscreen mode Exit fullscreen mode

All those component are assembled inside the AppModule and once everything builds we can call an URL and display the content.

Modules :

Modules help organize an application into cohesive functionality blocks by wrapping components, pipes, directives, and services. They are just all about developer ergonomics.

The good thing about angular is the fact that it's modular. Every Angular application has at least one module— the root module, conventionally named AppModule. You cannot load a component if it was not declared in a module before.

An angular module is a class with @NgModule decorator with the following properties.

  • declarations: The classes that belong to this module and are related to views. There are three classes in Angular that can contain views: components, directives, and pipes.

  • exports: The classes that should be accessible to other modules components.

  • imports: Modules whose classes are needed by the components of this module.

  • providers: Services present in one of the modules which are going to be used in the other modules or components. Once a service is included in the providers, it becomes accessible in all parts of that application.

  • bootstrap: The root component which is the main view of the application. Only the root module has this property and it indicates the component that’s gonna be bootstrapped.

  • entry components: An entry component is any component that Angular loads imperatively, (which means you’re not referencing it in the template), by type.

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppRoutingModule } from './app.routes';
import { AppComponent } from './app.component';
import {CategoriesComponent} from '../app/components/categories/categories.component'
import {CategoriesService} from '../app/services/category.services'
import {CategoriesResolver} from '../app/resolvers/category.resolver'
import {SharedModule} from './shared/share.module'

@NgModule({
  declarations: [
    AppComponent,
    CategoriesComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    SharedModule
  ],
  providers: [CategoriesResolver, CategoriesService],
  bootstrap: [AppComponent]
})
export class AppModule { }
Enter fullscreen mode Exit fullscreen mode

Summary

To make an angular page working we need a template to display the Html page, a component which use a service to load data and sent it to the template, the format of the data to use is specified in models. Sometimes we may need a resolver which preloads the data before displaying it. To make the component work we need to register it in modules and to access it a URL is assigned to it in routes

What next to learn

There is still a lot to learn in Angular, many concepts to master I would love to learn more about observables and injectables and testing with angular.

I really like angular because in opposition to react it's a full front end framework and as an old school guy, I noticed most of the design patterns I learned in my software engineering course are implemented in Angular.

For now, that is all I learned this week but I hope I will not stop there, I will go deeper and learn more and stop being afraid of front end development and call myself a full-stack engineer.

By the end of my learning journey, I will call myself a 10x engineer

Top comments (2)

Collapse
 
negue profile image
negue

Hey,

these are quite many first steps, I guess this is a great intro into angular for beginners :)

Is there a reason that you need to use webpack? If not, you can just use the angular cli ng new / ng serve that way you don't have to fight with webpack :)

I hope I'm not rude in giving some best practices.

  • Every Observable.subscribe you probably should also unsubscribe it, without unsubscribing it can turn out into weird issues

  • No need to double the promises:

when you have this:

  return new Promise((resolve, reject) => {
            //get categories from local json file
            this.categoriesService.getCategories()
                .then(
                    categories => {
                        return resolve({
                            categories: categories,
                        });
                    },
                    err => {
                        return resolve(null);
                    }
                )
        });

You can use do this:

  return this.categoriesService.getCategories()
                .then(categories => ({
                            categories: categories,
                        })
                );
  • if you want you can import json files directly (like a version.json) or something instead of having it loaded by http

Also the tour of heroes gives also a nice starting point for beginners :)

Collapse
 
bbasabana profile image
Bosco Basabana

I am also Angular fun compared to sight and react because of its simplicity on certain things: generation of component, services etc.