RSS

Tag Archives: angular

NgRx State Selectors

NgRx State Selectors

As our application grows, the data structure that represents the application states could get more complex. State data structure in ngRx is tree-like and in the early development, the structure may only have few properties. As the application grows, the structure could have deep nested objects.

When states have deep nested objects, we will have to write more code to select the slice of state. Something like:

// Complex data structure
let state = {
    products: {
        pizza: {
            name: "Pepperoni",
            amount: 4
        },
        topping: {
            name: "mushroom",
            amount: 3
        }
    }
};

// Selecting pizza state
let pizza = state.products.pizza;

Selecting pizza state requires dot notation and it’s also prone to error where products is undefined, that line of code will blow up.

Another issue with this is that we will have to write the same line of code to get pizza state every where we need the state.

This is where state selectors in ngRx comes in. It allows us to define selectors for our states and use it everywhere in our application.

There are mainly 2 state selectors, createFeatureSelector and createSelector. The first one mainly deals with state at the root level while the second one can be used to select a specific object in the state (for example, pizza or topping).

Reference

https://toddmotto.com/ngrx-store-understanding-state-selectors

Advertisements
 
Leave a comment

Posted by on December 12, 2018 in General

 

Tags: , , , , ,

NgRx Store Explained

NgRx Store

ngRx Store is a library for Angular 2+, its function is almost like event bus where the store is a central storage for all events and whenever an event is added, the store emits an action. Whoever subscribe to the store‘s action will then get notified. Very similar to pub-sub pattern.

The purpose of ngRx Store is to simplify the state management, that sometime can be simple at first but, as the application grows, becomes unimaginably complicated.

Some example usage of ngRx Store that I can think right now are:

  • Forward execution. When an Angular application sends an API call to update, let’s say, employee data, it doesn’t need to call API anymore to query what the current employee data is. However, things get complicated when there’s a certain logic needs to be applied when updating employee data. For example, when the hire date is set to the future, the employee status will also need to be changed. ngRx Store can be used to manage the employee state so that it remains consistent at every part of the application.
  • Reduce extraneous props. Extraneous prop is when we have a deep component tree and have to pass object around to the leaf component. ngRx Store eliminates the need of passing the object around and just have the leaf component subscribe to the `store` to receive the action. A concrete example of this is notification counter. The counter is normally in its own component and every other event can increase the count. By using ngRx Store, we can avoid other components passing the count to the counter component.
  • Sort of the similar to extraneous props, we can have 2, or more, components that use the same data but display it differently. with ngRx Store, we can manage the state of the data in one place and all other components that use the data just subscribe to it.
  • Step-by-step, wizard-y workflow. Think of this like your tax filing software where it asks you questions and, depend on your answer, take you to different workflow. In Angular, each step the users take can use a separate component and ngRx Store can be used to maintain the state of the whole workflow process.

The problem that ngRx Store trying to solve is really similar to challenges that a large scale enterprise application faces, it just does it in a smaller scale, UI front-end in this case.

There’s definitely a lot more to this concept than what I cover here, but hopefully this gives you the gist of how it works at the high level. There are lots of resources online that cover this very topic.

 
Leave a comment

Posted by on December 1, 2018 in General

 

Tags: , , , , ,

Barebone Angular Project with Auth0

Simple project to demonstrate how to use Auth0 in Angular project, download code on Github.

To get started, you must have Auth0 account.
To setup the project, update following value in `environment.ts`:
1. Client ID. This is the id of your app you created in Auth0 dashboard. See here.
2. Client Domain. Your Auth0 domain to authenticate user. See here.
3. Callback Url. This is url Auth0 will redirect to after user is authenticated. This url must be white-listed in Auth0 dashboard. See here.
4. Logout Url. This is url Auth0 will redirect to after user logout. This url must be white-listed in Auth0 dashboard. See here.

The juice is on `service/auth.service.ts`, following are explanations of each methods:
1. Login
Call Auth0 authorize method to authenticate users. The method will redirect user to Auth0, if user is not authenticated, a login screen will displated, if user is authenticated Auth0 will redirect to callback endpoint and pass id token.

2. HandleAuthentication
Parse response object from Auth0 which contain id token, access token, expiration time and other information. Redirect user to appropriate url depend on the authorization results.

3. SetSession
Set authentication tokens and expiration in browser’s storage. User is authenticated.

4. Logout
Remove authentication tokens and expiration from browser’s storage. User is not authenticated anymore.

5. IsAuthenticated
Check browser’s storage to see if user is authenticated.

 
Leave a comment

Posted by on November 27, 2018 in General

 

Tags: , , , , , ,

Karma: Only Run 1 Test

Useful hack to only run 1 test in Karma.

Instead of ‘it’, change test declaration to ‘fit’.
Example:

    fit('should create', () => {
        expect(component).toBeTruthy();
    });

This will force Karma to only run ‘should create’ test.

 
Leave a comment

Posted by on October 22, 2018 in General

 

Tags: , , , , , ,

“The CodeDom provider type Microsoft.VisualC.CppCodeProvider could not be found” exception

This problem happened when you build project/solution in Visual Studio. Generally caused when you have compile-able files in your Visual Studio solutions but VS could not understand it.
In my case, I have infamous ‘node_modules’ folder.

To solve this issue, in Windows Explorer, I right click on it ‘node_modules’ folder and select ‘Properties’, check ‘Hidden’ under Attributes.

You can also exclude the folder. In Visual Studio Solution Explorer, right click on ‘node_modules’ and select ‘Exclude From Project’.

More reading.

 
Leave a comment

Posted by on September 12, 2018 in General

 

Tags: , , , , , , ,

Angular 6 Custom Elements’ Properties

If you are not familiar with Angular custom elements, read my previous post.

Here is tips on how to expose properties from your custom element so the user can do something like this:

<body>
  <fooComponent></fooComponent>

  <script>
    if (document.readyState === 'complete') {
      document.querySelector('fooComponent').value = 'i am value-able';
      document.querySelector('fooComponent').fooProp = 'i am foo prop';

      console.log(document.querySelector('fooComponent').value);
      console.log(document.querySelector('fooComponent').fooProp);
    }
  </script>
</body>

First, this is our custom component, same setup as my previous post.

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule, Injector } from '@angular/core';
import { createCustomElement } from '@angular/elements';

import { AppComponent } from './app.component';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule
  ]
  entryComponents: [
    AppComponent
  ]
})
export class AppModule {
  constructor(private injector: Injector) {
    let customComponent = createCustomElement(AppComponent, { injector });
    window.customElements.define('fooComponent', customComponent);
  }

  ngDoBootstrap() {
  }
}

And how to expose properties.

app.component.ts

import { Component, Input, SimpleChanges } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  // Element's properties to expose
  @Input() value: string;
  @Input() fooProp: string;

  // Track changes of the properties
  ngOnChanges(changes: SimpleChanges): void {
    console.log(changes.value.currentValue);
    console.log(changes.fooProp.currentValue);
  }
}

Note here, though we use Angular’s Input directive, it also allow user to modify property value, so it’s important to validate before using it.

That’s it. Simple.

 
Leave a comment

Posted by on September 12, 2018 in General

 

Tags: , , , ,

Angular – All Possible Solutions for ‘No NgModule’

The error “No NgModule metadata found for ‘AppModule'” could be caused by various reason:

  1. Moving Angular project folder.
  2. Upgrading dependencies.
  3. Upgrading Angular version.

Here are summary of all possible answers I have found during my battle. All answers are from Github and Stackoverflow.

  1. You are trying to bootstrap App, which is not a real module. Instead, bootstrap Module. Source.
  2. A simple edit in the app.module.ts file ( like delete a bracket and put it back) did the trick. Source.
  3. This one work for me. Try to remove node_modules and package-lock.json then run npm install. Source.
  4. Arrange include list in tsconfig.json so that the app.module.ts was located first. Source.
  5. Remove webpack, install latest angular/cli, delete node_module, clear cache, reinstall angular/cli, then run npm install. Source.
  6. Upgrading angular/cli. Source.
  7. App.module.ts has extra comma. Source.
  8. Change import path in App.module.ts. Source.
 
Leave a comment

Posted by on September 7, 2018 in General

 

Tags: , , , , ,

 
%d bloggers like this: