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-base-state

v1.0.4

Published

Base classes for creation state service via Rxjs observable

Downloads

29

Readme

ngx-base-state 🐍

npm npm Build status

Classes have implemented base work with state

Idea

The main idea of this library is remove useless code from class. Usually state services violate DRY pattern
This library will help to create state in 3 lines.

Wiki

Visit wiki page to get more useful information.

Installation

npm install ngx-base-state --save

OPTIONAL: If you want to use Devtools to explore your state via Chrome Extension:

In your AppModule

import { NgxBaseStateDevtoolsModule } from 'ngx-base-state';
import { environment } from 'src/environments/environment'; 

@NgModule({
    imports: [
        NgxBaseStateDevtoolsModule.forRoot({ isEnabled: !environment.production })
    ]
})
export class AppModule {}

Chrome Extension

This tool allows you to see data in your states based on ngx-base-state.

  • Install ngx-base-state extension from Chrome WebStore;
  • Open tab with your Application using ngx-base-state;
  • Press F12 to open Devtools;
  • Choose ngx-base-state panel in devtools;

Main page will contain list of all your states. Click to some state and will opened "details page" with state changes history.

List of States | List of Actions | State details | :-----------------------------------------------------------------------------:|:------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------:| | | |

Properties & Methods

BaseState

Base class for all kinds of states. You can create your abstract class based on BaseState to store the necessary custom data.

| Name | Type | Description | |:-------------------|:---------------------------|:--------------------------------------------------------------------| | data$ | Observable<T | null> | state data stream | | data | T | state data | | set | value: T (generic type) | set new value for state | | clear | | clear value in the state | | restoreInitialData | | restore initial data from constructor. |

ObjectState

Extend your class from ObjectState to store the object.

Contains all fields and methods like at BaseState, and also:

| Name | Arguments | Description | |:----------------- |:---------------------------|:--------------------------------------------------------------------| | updateWithPartial | value: Partial<T> | update state by merging current state with new partial object |

RecordState

Extend your class from RecordState to store the object with Record interface.

Store data in key -> value format.

Contains all fields and methods like at BaseState, and also:

| Name | Arguments | Description | |:----------------- |:---------------------------|:--------------------------------------------------------------------| | keys$ | | stream with all keys of your Record object | | keys | | all keys of your Record object | | values | | all values of your Record object | | values$ | | stream with all values of your Record object | | setItem | key: TKey, value: TValue | set item by key into state's object | | removeItem | key: TKey | remove item by key from state's object | | removeAllItems | | remove all items from state's object |

ArrayState

Extend your class from ArrayState to store the array.

Contains all fields and methods like at BaseState, and also:

| Name | Arguments | Description | |:------------------|:----------------------------|:-------------------------------------------------------------------------------- | | getItemId | item: T | protected method might be overridden, it used for comparing items in array | | set | value: T[] | set new array for state | | pushItem | item: T | push new item to array | | unshiftItem | item: T | unshift item to array | | shift | | shift array | | pop | | pop array | | insertItemByIndex | index: number, item: T | insert item in array by index. | | updateItem | itemToUpdate: T | update item in array | | updateItemByIndex | item: T, index: number | update item in array by index | | concatWith | array: T[] | concat current state with another array | | removeItem | item: T | remove item from array | | removeItemById | itemId: unknown | remove item from array by id (define id by overriding getItemId method) | | removeItemByIndex | index: number | remove item from array by index |

PrimitiveState

Extend your class from PrimitiveState to store the: number, string, boolean, enum, type etc...

Contains all fields and methods like at BaseState and currently nothing else.

Example with ObjectState

user.state.ts

import { ObjectState, NgxState } from 'ngx-base-state';

// So easy to create new State :)
@NgxState()
@Injectable({
  providedIn: 'root'
})
class UserState extends ObjectState<User> {}

user.service.ts

import { User } from '../interfaces';
import { UserApi } from '../api';
import { UserState } from '../states';

// IMPORTANT: Work with states only via "Service" layer.
@Injectable({
  providedIn: 'root'
})
class UserService {
  // Share data for components.
  public readonly data$ = this.userState.data$;

  constructor(
    private readonly userApi: UserApi,
    private readonly userState: UserState
  ) {}

  // Make your methods with business logic, which might affect states.
  // Return Observable. Components can process result by subscribing (complete/next/error).
  public update(): Observable<User> {
    return this.userApi.getCurrent()
      .pipe(
        tap((user) => this.userState.set(user))
      );
  }
}

user.component.ts

import { ToastService } from '@my-library';
import { UserService } from '@features/user';

// IMPORTANT: Don't inject States directly to components!
// Only services with business logic should know how to affect your states.
@Component({
  selector: 'smart-user',
  template: '{{ user$ | async | json }}'
})
class UserComponent implements OnInit {
  // Here is data from our state.
  public readonly user$ = this.userService.data$;

  constructor(
    private readonly userService: UserService,
    private readonly toastService: ToastService
  ) {}

  public ngOnInit(): void {
    this.updateUser();
  }

  // Run some services business logic from the smart component
  private updateUser(): void {
    this.userService.update()
      .pipe(
        catchError(() => this.showErrorToastAboutUserUpdatingError())
      )
      .subscribe();
  }

  // This is task of specific smart components to show UI staff, like: toasts, dialogs, bottomSheets etc...
  private showErrorToastAboutUserUpdatingError(): Observable<unknown> {
    return this.toastService.createError(`Can't update user!`);
  }
}

Example with ArrayState

users.state.ts

import { ArrayState, NgxState } from 'ngx-base-state';
import { UserFilters } from '../interfaces';

@NgxState()
@Injectable({
  providedIn: 'root'
})
class UsersState extends ArrayState<User> {
  constructor() {
    super([]); // Here you can set initial data.
  }

  // Example of "custom action"
  public filter(filters: UserFilters): void {
    const newUsers = this.data!.filter((user) => user.name.includes(filters.searchString));

    this.set(newUsers);
  }

  // ArrayState have base methods to work with array, like: removeItem, updateItem
  // and these methods might compare items in array using some unique value.
  // You can override method `getItemId` if you want operate with items via specific unique value like `id`.
  protected override getItemId(user: User): number {
    return user.id;
  }
}

users.service.ts

import { UsersState } from './users.state';

// This service demonstrates examples of work with methods of ArrayState.
@Injectable({
  providedIn: 'root'
})
export class UsersService implements OnInit {
  // Async data for components.
  public readonly data$ = this.usersState.data$;

  // Sync data for components.
  public get data(): User {
    return this.usersState.data;
  }

  constructor(
    private readonly usersState: UsersState
  ) {
    this.usersState.data$
      .subscribe(console.log);

    this.setUserArray();  // [{ name: 'Nillcon', id: 248 }, { name: 'noname', id: 1 }]
    this.updateUser()  // [{ name: 'New name', id: 248 }, { name: 'noname', id: 1 }]
    this.removeUser(); // [{ name: 'New name', id: 248 }]
    this.addUser(); // [{ name: 'New name', id: 248 }, { name: 'John Doe', id: 2 }]
  }

  private setUserArray(): void {
    this.usersState.set([
      {
        name: 'Nillcon',
        id: 248
      },
      {
        name: 'noname',
        id: 1
      }
    ]);
  }

  private updateUser(): void {
    let user = this.usersState.data[0]; // { name: 'Nillcon', id: 248 }
    user.name = 'New name';

    // ngx-base-state will create new instance of user to avoid possible object mutations
    this.usersState.updateItem(user);
  }

  private removeUser(): void {
    const user = this.usersState.data[1]; // { name: 'noname', id: 1 }

    this.usersState.removeItem(user);
  }

  private addUser(): void {
    this.usersState.pushItem({
      name: 'John Doe',
      id: 2
    });
  }
}