rxjs-observed-decorator
    TypeScript icon, indicating that this package has built-in type declarations

    1.0.0 • Public • Published

    rxjs-observed-decorator

    Adds a drop-dead simple decorator which ties a class variable to an RxJS Subject.

    Installation

    npm install rxjs-observed-decorator --save
    

    Requires you to add "experimentalDecorators": true, to tsconfig.json

    // tsconfig.json
    {
        "compilerOptions": {
            ...
            "experimentalDecorators": true,
            ...
        }
    }
    

    Important Usage Notes

    • Properties defined with @Observed should always be initialized (Subject to change).
    @Observed() property: string;               // BAD ❌
    @Observed() property = '';                  // GOOD ✅
    @Observed() property: string = null;        // GOOD ✅
    • Classes with @Observed properties should always be instantiated.
    • Do not attempt to initialize the Observable property. The decorator handles that for you.
    • If you are using strict mode, you can add ! to your observable definitions to avoid errors.
    @Observed() property = '';
    readonly property$!: Observable<string>;

    Angular Examples

    A simple Service with an @Observed() property

    @Injectable({ providedIn: 'root' })
    export class UserService {
        
        @Observed() users: User[] = null;
        readonly users$!: Observable<User[]>;
    
        constructor(private http: HttpClient) {}
    
        getUsers() {
            this.http.get('users').subscribe(users => {
                
                // the property setter calls '.next()' behind the scenes
                this.users = users;
    
            });
        }
    
    }

    A simple Component that uses the service's Observable

    @Component({ ... })
    export class UserListComponent implements OnInit {
    
        users$: Observable<User[]>;
    
        constructor(private userService: UserService) {
        }
    
        ngOnInit() {
            this.users$ = this.userService.users$;
    
            this.userService.getUsers();
        }
    }

    Component Template

    <ng-container *ngIf="(users$ | async) as users else loading">
        <div *ngFor="let user of users">...</div>
    </ng-container>
    <ng-template #loading>Loading Users...</ng-template>

    Generic Examples

    Behavior Subject (default)

    export class MyClass {
    
        @Observed() myProperty = 'initial value';
        
        // Observable property is automatically created.
        readonly myProperty$!: Observable<string>;
    
        constructor() {}
    }
    
    const instance = new MyClass();
    
    instance.myProperty$.subscribe(value => console.log(value));
    
    instance.myProperty = 'a'; 
    instance.myProperty = 'b';
    instance.myProperty = 'c';
    
    // output:
    
    // initial value
    // a
    // b
    // c

    Subject

    export class MyClass {
    
        @Observed({ type: 'subject' }) 
        myNumber: number = null;
        
        readonly myNumber$!: Observable<number>;
    
        constructor() {}
    }
    
    const instance = new MyClass();
    
    instance.myNumber = 1; 
    
    instance.myNumber$.subscribe(value => console.log(value));
    
    instance.myNumber = 2;
    instance.myNumber = 3;
    
    // output:
    
    // 2
    // 3

    Replay Subject

    See RxJS ReplaySubject for replayOptions

    interface Animal {
        mass: number;
        color: string;
    }
    
    export class MyClass {
    
        @Observed({ type: 'replay', replayOptions: {} }) 
        animal: Animal = null;
        
        readonly animal$!: Observable<Animal>;
    
        constructor() {}
    }
    
    const instance = new MyClass();
    
    instance.animal = { mass: 50, color: 'orange' }; 
    
    instance.animal$.subscribe(animal => console.log(`mass: ${ animal.mass }, color: ${ animal.color }`));
    
    instance.animal = { mass: 60, color: 'green' };
    instance.animal = { mass: 10, color: 'blue' };
    
    // output:
    
    // mass: 50, color: orange
    // mass: 60, color: green
    // mass: 10, color: blue

    Options

    Observed() Decorator takes in an optional parameter for options.

    class A {
        @Observed({ type: 'subject' }) prop = '';
    }
    Option Possible Values Notes
    type 'subject'
    'replay'
    'behavior'
    Default value is 'behavior'
    replayOptions See RxJS ReplaySubject Should only be used with type: 'replay'

    The default value for options is { type: 'behavior' }.

    Install

    npm i rxjs-observed-decorator

    DownloadsWeekly Downloads

    2

    Version

    1.0.0

    License

    ISC

    Unpacked Size

    12.3 kB

    Total Files

    9

    Last publish

    Collaborators

    • avatar