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

@webacad/angular-json-api

v5.2.1

Published

Angular module for working with data from standardized json api

Downloads

15

Readme

NPM version Build Status

WebACAD/AngularJsonApi

Angular module for working with data from standardized json api

Installation

Version >= 5.0.0 depends on angular >= 6. For older versions of angular use @webacad/angular-json-api@^4.0.

$ npm install --save @webacad/angular-json-api

or with yarn

$ yarn add @webacad/angular-json-api

Register the module

import {NgModule} from '@angular/core';
import {JsonApiModule, JsonApiRootModuleConfiguration} from '@webacad/angular-json-api';

const apiConfig: JsonApiRootModuleConfiguration = {
    url: 'https://example.com/api',
    entities: [],
};

@NgModule({
    imports: [
        JsonApiModule.forRoot(apiConfig),
    ],
})
export class AppModule {}

You must provide the base url to your API

Create entities

There are several decorators which you can use to define your entity. They are later used for mapping the data from API to these entities.

import {Entity, Id, Column, Relationship} from '@webacad/angular-json-api';
import {Role} from './role';

@Entity({
    type: 'user',
})
export class User
{

    @Id()
    public readonly id: string;
    
    @Column({
        name: 'name',
    })
    public readonly name: string;
    
    @Relationship({
        name: 'roles',
    })
    public roles: Array<Role>;

}

@Column() options:

  • name: name of key in json data source. Default value is the name of property.

@Relationship() options:

  • name: name of key in json data source. Default value is the name of property.

Register in app:

Last thing is to update the API configuration for your app:

import {Role} from './role';
import {User} from './user';

const apiConfig: JsonApiRootModuleConfiguration = {
    url: 'https://example.com/api',
    entities: [
        Role,
        User,
    ],
};

Child modules

The entities array for your configuration has a potential to grow really fast. If you split your model classes into modules, you could register entities in their respective modules too.

import {NgModule} from '@angular/core';
import {JsonApiModule, JsonApiChildModuleConfiguration} from '@webacad/angular-json-api';
import {Role} from './role';
import {User} from './user';

const apiConfig: JsonApiChildModuleConfiguration = {
    entities: [
        Role,
        User,
    ],
};

@NgModule({
    imports: [
        JsonApiModule.forChild(apiConfig),
    ],
})
export class UsersModule {}

JsonApiClient

JsonApiClient service is a simple wrapper around the new HttpClient from angular.

It takes care of prefixing all of your urls with provided url in the app configuration and mapping the data into your entities.

Methods:

  • get<T>(url: string, options: JsonApiRequestOptions = {}): Observable<T>
  • post<T>(url: string, body: any|Observable<any>, options: JsonApiRequestOptions = {}): Observable<T>
  • put<T>(url: string, body: any|Observable<any>, options: JsonApiRequestOptions = {}): Observable<T>
  • delete<T>(url: string, options: JsonApiRequestOptions = {}): Observable<T>

Options:

  • includes: list of relationships you want to include in the response from API
  • parameters: additional URL parameters to be send
  • transform: (default true, false for delete requests), if set too false you'll get the raw data from angular http client

Example:

import {JsonApiClient} from '@webacad/angular-json-api';
import {Observable} from 'rxjs/Observable';
import {User} from './user';

export class UsersRepository
{
    
    constructor(
        private api: JsonApiClient,
    ) {}
    
    public getById(id: number): Observable<User>
    {
        return this.api.get<User>(`users/${id}`);
    }
    
}

Custom column types

All values inserted into columns are taken from the json data without any change.

Custom column type can be used to transform the raw column value into something else. This can make things like transforming timestamps into Date objects really easy.

1. write the transform function:

function timestampToDate(timestamp: number): Date
{
    return new Date(timestamp * 1000);
}

2. register type into your app:

const apiConfig = {
    url: '',
    entities: [],
    types: {
        myCustomDate: timestampToDate,
    },
};

3. use in entity:

@Entity({
    type: 'article',
})
class Article
{

    @Id()
    public readonly id: string;

    @Column({
        type: 'myCustomDate',
    })
    public readonly createdAt: Date;

}

Column transformers

Column transformers are similar to column types described above. But where column types are global, column transformers are local.

You may have some entity which has a unique way of handling one of it's columns. One option is to create the getter and setter for such column, but that just makes the code less readable. Better option is to use column transformer:

First define transformer function:

function dateTimeFromTimestamp(timestamp: number): Date
{
    return new Date(timestamp * 1000);
}

Second used it in your entity:

@Entity({
    type: 'article',
})
class Article
{

    @Id()
    public readonly id: string;

    @Column({
        transformers: [
            dateTimeFromTimestamp,
        ],
    })
    public readonly createdAt: Date;

}

As you can see, the transformers option accepts an array. That means that you can attach multiple transformers to one column. In that case the first transformer will be applied first on mapping.

If the column has type option too, the transformers option will be applied after type mapping.

Optional column

If some column data is missing in the API json, this library will throw an exception. This behavior can be disabled by marking the column as optional. Just add the @Optional() decorator:

@Entity({
    type: 'article',
})
class Article
{

    @Id()
    public readonly id: string;

    @Column()
    @Optional()
    public readonly author: any;

}

Mapping to entities

If you use the methods above for accessing your API, the returned data will be automatically mapped to the correct entity class.

When using auto mapping, the constructor is not called!

Custom entity mapper

@Entity({
	type: 'article',
	mapper: (mapping, data, config) {
		// todo: create Article instance manually
	},
})
class Article
{
	
	// ...
	
}