Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular2 EventEmitter with last value

Basically I want to know is there a way to get last value from EventEmmiter right after I have subscribed to it?

Why I need this. Imagine a list component that uses two more components: filter and grid. Filter provides filter event and grid provides sorting event.

In my list component I want to write code like this:

        Observable
            .combineLatest(filtering$, sorting$)
            .switchMap(([filter, sorting]) => {
                return this.api.list(filter, sorting);
            })
            ...

Very short elegant code. But there are two problems:

  1. EventEmitter is not observable. It is not much of a problem because I can easily wrap it with observable.
  2. Call to API will not be performed until every observable fires at least once. This is a real problem.

Currently I am solving it with BehaviorSubject from RxJs:

Represents a value that changes over time. Observers can subscribe to the subject to receive the last (or initial) value and all subsequent notifications.

In my filter component I have:

class UsersListFilter {
    private filteringSource = new BehaviorSubject<UserFilter>(new UserFilter());
    filtering$ = this.filteringSource.asObservable();

    ...
}

And in my list component:

class UsersList {
    @ViewChild(UsersListFilter) private filter: UsersListFilter;
    ...

    setupDataReloading() {
        Observable
            .combineLatest(this.filter.filtering$, this.grid.sorting$)
            ...
    }
}

As you can see I do not use EventEmitter at all. But this solution feels kinda unnatural in Angular2 because I am ignoring standard way of interacting with child component (@Output).

Any thoughts?

like image 811
Sergey Sokolov Avatar asked May 12 '26 19:05

Sergey Sokolov


1 Answers

Use this custom class instead

import { EventEmitter } from '@angular/core';

import { ObjectUnsubscribedError } from 'rxjs';


export class CustomEventEmitter<T> extends EventEmitter<T> {

    private _value: T;

    constructor() {
        super();
    }

    get value(): T {
        return this.getValue();
    }

    getValue(): T {
        if (this.hasError) {
            throw this.thrownError;
        } else if (this.closed) {
            throw new ObjectUnsubscribedError();
        } else {
            return this._value;
        }
    }

    emit(value?: T) {
        super.emit(this._value = value);
    }
}
like image 53
marcosvolpato Avatar answered May 14 '26 13:05

marcosvolpato



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!