npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

ngx-decorator

v1.1.1

Published

Set of useful decorators for Angular

Downloads

15

Readme

ngx-decorator

Set of useful decorators for Angular.

NPM Version NPM Downloads

Installation

npm install ngx-decorator --save

Supported decorators

Lifecycle hooks decorators

Decorators for Angular lifecycle management

@TakeUntilDestroy

@TakeUntilDestroy - unsibscribes from an Observeble on ngOnDestroy lificycle hook: First you need to decorate your component class which implements OnDestroy interface with @TakeUntilDestroy decorator:

import { TakeUntilDestroy } from 'ngx-decorator';

@TakeUntilDestroy
export class CounterComponent implements OnInit, OnDestroy {}

Next step is to create private field componentDestroy: Function in your component and use it in pipe method with rxjs takeUntil operator:

import { TakeUntilDestroy } from 'ngx-decorator';

@TakeUntilDestroy
export class CounterComponent implements OnInit, OnDestroy {

    private componentDestroy: Function;

    constructor() { }

    ngOnInit() {
        interval(2000).pipe(
            takeUntil(this.componentDestroy())
        ).subscribe(() => {
            console.log('Interval tick');
        });
    }

    ngOnDestroy() {
    }
}

@TrackChanges

@TrackChanges - binds @Input field to execution of component method with provided changes strategy: Decorator accepts 3 argumaents: - key - name of @Input() field - methodName - name of method to be called when - strategy - ChangesStrategy enum

export enum ChangesStrategy {
    First = 'First', // listen only first change
    Each = 'Each', // listen each change
    NotFirst = 'NotFirst' // listen all changes except first
}

In this snippet counterChange method will be called on every data-bound property change of @Input() counter field using ChangesStrategy.NotFirst:

import { TrackChanges, ChangesStrategy } from 'ngx-decorator';

export class CounterComponent implements OnChanges {

    @Input()
    counter: number;

    constructor() { }

    @TrackChanges<number>('counter', 'counterChange', ChangesStrategy.NotFirst)
    ngOnChanges() {
    }

    counterChange(): void {
        console.log(`Counter changed to ${this.counter}`);
    }
}

Utils decorators

Useful utils decorator for Angular

@Safe

@Safe - catches application errors and forwards them to proper errorHandler depending on SafeLogLevel provided: Decorator accepts 1 argumaent of type SafeParams<T>:

export interface SafeParams<T> {
    logLevel?: SafeLogLevel; // Decorator LogLevel (see below)
    returnValue?: T; // returnValue if error was thrown
}

Available Log Levels:

export enum SafeLogLevel {
    Default = 'Default', // if error was thrown only get returnValue
    Console = 'Console', // log error to console
    ErrorHandler = 'ErrorHandler' // forward error to errorHandler. Class with 'Safe' decorator and logLevel 'ErrorHandler' should have 'errorHandler' class property with 'ErrorHandler' class.
}

Decorate any method in component with @Safe decorator in following way:

import { Safe, SafeLogLevel } from 'ngx-decorator';

export class CounterComponent implements OnInit, OnChanges, OnDestroy {

    constructor(private errorHandler: ErrorHandler) { }

    ngOnInit() {
        const result = this.throwErr(); // result value is false
    }

    @Safe<boolean>({
        logLevel: SafeLogLevel.ErrorHandler,
        returnValue: false
    })
    throwErr() {
        throw new Error('err thrown');
    }
}

Then see error in your ErrorHandler class:

class MyErrorHandler implements ErrorHandler {
    handleError(error) {
        console.log('Handling error:', error);
    }
}

@Cache

@Cache - caches results of functions: Decorator accepts 1 argumaent of type CacheParams<T>:

export interface CacheParams {
    cacheKey?: string; // key name used to access cache data. You can provide your own or keep default (then name of called method will be used)
    useParamsAsKeys?: boolean; // if true cache will be stored depending on method arguments, if false every call to function will extract data from cache.
}

Store result of a function in cache:

import { Cache, Safe } from 'ngx-decorator';

export class CounterComponent implements OnInit {

    constructor() { }

    ngOnInit() {
        console.log(
            this.add(10, 20),
            this.add(20, 30),
            this.add('str', 10),
            this.add(10, 20), // <------- result of this call will be taken from cache
        );
    }

    @Safe<number>({ returnValue: null })
    @Cache({
        cacheKey: 'myKey',
        useParamsAsKeys: true
    })
    add(a, b) {
        if (typeof a !== 'number' || typeof b !== 'number') {
            throw new Error('invalid arguments');
        }

        return a + b;
    }
}

In this snippet result of forth call to this.add will be retrived from cache.

@OutsideAngular

@OutsideAngular - escape Angular's zone and do work that doesn't trigger Angular change-detection Decorator does not accepts parameters:

import { OutsideAngular } from 'ngx-decorator';

export class AppComponent implements OnInit {
    counter = 0;

    constructor(private ngZone: NgZone) {}

    ngOnInit() {
        this.processOutsideOfAngularZone();
    }

    @OutsideAngular
    processOutsideOfAngularZone() {
        this.increaseProgress(() => {
            this.ngZone.run(() => { console.log('Outside Done!'); });
        });
    }

    increaseProgress(doneCallback: () => void) {
        this.counter += 1;
        console.log(`Current progress: ${this.counter}%`);

        if (this.counter < 10) {
            window.setTimeout(() => this.increaseProgress(doneCallback), 1000);
        } else {
            doneCallback();
        }
    }
}

In this snippet each tick of increaseProgress function willbe executed in Angular's parent zone

HTTP decorators

To start using http decorators first you need to decorate you class with @HttpApi decorator:

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

import { HttpApi } from 'ngx-decorator';

@Injectable()
@HttpApi('api')
export class DataService {

    constructor(private httpClient: HttpClient) { }
}

@HttpApi decorator is used to define base API url. For example in this url - /api/user/1488, api is base url. Once base url defined you can start using http decorators:

@Get

@Get - makes HTTP GET request with HttpParams:

...
import { HttpApi, Get } from 'ngx-decorator';

@Injectable()
@HttpApi('api')
export class DataService {

    constructor(private httpClient: HttpClient) { }

    @Get('users')
    getOne(params?: object): Observable<any> { // <-------- makes GET request to /api/users with params defined
        return of();
    }
}

@Post

@Post - makes HTTP POST request with HttpParams:

...
import { HttpApi, Post } from 'ngx-decorator';

@Injectable()
@HttpApi('api')
export class DataService {

    constructor(private httpClient: HttpClient) { }

    @Post('users/save')
    addAll(params?: object, body?: object): Observable<any> { // <-------- makes POST request to /api/users/save with params and request body defined
        return of();
    }
}

@Put

@Put - makes HTTP PUT request with HttpParams:

...
import { HttpApi, Put } from 'ngx-decorator';

@Injectable()
@HttpApi('api')
export class DataService {

    constructor(private httpClient: HttpClient) { }

    @Put('users/save')
    replaceAll(params?: object, body?: object): Observable<any> { // <-------- makes PUT request to /api/users/save with params and request body defined
        return of();
    }
}

@Patch

@Patch - makes HTTP PATCH request with HttpParams:

...
import { HttpApi, Patch } from 'ngx-decorator';

@Injectable()
@HttpApi('api')
export class DataService {

    constructor(private httpClient: HttpClient) { }

    @Patch('users/save')
    replaceOne(params?: object, body?: object): Observable<any> { // <-------- makes PATCH request to /api/users/save with params and request body defined
        return of();
    }
}

@Delete

@Delete - makes HTTP DELETE request with HttpParams:

...
import { HttpApi, Delete } from 'ngx-decorator';

@Injectable()
@HttpApi('api')
export class DataService {
    
    constructor(private httpClient: HttpClient) { }

    @Delete('users')
    removeAll(params?: object): Observable<any> { // <-------- makes DELETE request to /api/users with params defined
        return of();
    }
}

@Request

@Request - makes HTTP request with defined method:

...
import { HttpApi, Request } from 'ngx-decorator';

@Injectable()
@HttpApi('api')
export class DataService {
    
    constructor(private httpClient: HttpClient) { }

    @Request('GET', 'users')
    getOneRequest(params?: object): Observable<any> { // <-------- makes GET request to /api/users with params defined
        return of();
    }

    @Request('POST', 'usrs/save')
    addAllRequest(params?: object, body?: object): Observable<any> { // <-------- makes POST request to /api/users/save with params and request body defined
        return of();
    }

    @Request('PUT', 'usrs/save')
    replaceAllRequest(params?: object, body?: object): Observable<any> { // <-------- makes PUT request to /api/users/save with params and request body defined
        return of();
    }

    @Request('PATCH', 'usrs/save')
    replaceOneRequest(params?: object, body?: object): Observable<any> { // <-------- makes PATCH request to /api/users/save with params and request body defined
        return of();
    }

    @Request('DELETE', 'usrs')
    removeAllRequest(params?: object): Observable<any> { // <-------- makes DELETE request to /api/users with params defined
        return of();
    }
}