Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Question] Does the ng2 ui router work with observables? #3085

Closed
bastienJS opened this issue Oct 12, 2016 · 9 comments
Closed

[Question] Does the ng2 ui router work with observables? #3085

bastienJS opened this issue Oct 12, 2016 · 9 comments

Comments

@bastienJS
Copy link

Searching for ng2 ui router information I read lots about promises.

I am using observables in my application. Can ng2 ui router handle observables?

@ValentinFunk
Copy link
Contributor

You can use the ng2 router with observables if you use the RXWAIT policy:

let state = {
    name: "observable",
    url: "/obs",
    resolve: [
        {
            provide: 'myobservable', useFactory: (myService: MyService) => {
                return myService.observable$;
            },
            deps: [MyService],
            policy: { async: "RXWAIT" }
        },
    ]
};

You can inject myobservable into your component normally and it will resolve to the observable once the first element has been emitted.

At the moment there are however a few bugs with the implementation, there is some discussion and a workaround here: #3067

@bastienJS
Copy link
Author

Thanks, then I will wait for proper observables support :-)

@jspizziri
Copy link

@kamshak,

Can you clarify how the observable is injected? Is it via an @Input() annotated property or via a constructor?

Here's what I've attempted:

// my.states.ts
...
  {
    name: 'mystate',
    url: '/mystate',
    component: MyComponent,
    resolve: [
      {
        provide: 'myObservable',
        useFactory: (someService: SomeService) => {
          return someService.fetch();
        },
        policy: { async: 'RXWAIT' },
        deps: [SomeService]
      }
    ]
  },
...
// my.component.ts
...
@Input() myObservable: Observable<My>;
protected my: My;

ngOnInit() {
  this.myObservable.subscribe(my => this.my = my);
}
...

Thanks in advance!

@ValentinFunk
Copy link
Contributor

ValentinFunk commented Oct 25, 2016

@jspizziri, you would inject is as any other resolve via a constructor inject. So for example:

state

{
    name: 'mystate',
    url: '/mystate',
    component: MyComponent,
    resolve: [
      {
        provide: 'myObservable',
        useFactory: (someService: SomeService) => {
          return someService.fetch();
        },
        policy: { async: 'RXWAIT' },
        deps: [SomeService]
      }
    ]
  },

component

import { Injectable } from "@angular/core";
@Component {
    template: '<h1>{{ myObservable | async }}</h1>
}
class MyComponent {
     constructor(@Inject('myObservable') public myObservable) { }
}

@jspizziri
Copy link

Thanks @kamshak!

One more question though. When I do that I'm getting the following error:

TypeError: observable$.cache is not a function

I'm not sure what's going on there. Any ideas? Thanks again!

@ValentinFunk
Copy link
Contributor

ValentinFunk commented Oct 25, 2016

Seems like you are using a RxJS Version with the cache operator removed. You can use [email protected] which still has it. I believe there are plans to rework the feature, mabye @christopherthielen or @adharris can give you some more info on the current state.

@christopherthielen
Copy link
Contributor

Yes, we need to rework the RXWAIT policy so it doesn't use .cache().

ReactiveX/rxjs#2012

please follow #3066

@MaZZly
Copy link

MaZZly commented Mar 17, 2017

while waiting for RXWAIT to be fixed you can wrap the Observable in a promise on the service:

public resolvePromise() {
    return new Promise((resolve, reject) => {
        let subscription = this.observableFunction().subscribe(
            (response) => resolve(response), // Success
            (error) => reject(error), // Error
            () => { // Cleanup
                if (subscription) { // HMR sometimes makes subscription undefined
                    subscription.unsubscribe();
                }
            });
    });
}

@hordesalik
Copy link

Currently, I'm able simply use Observable.prototype.toPromise() function:
this.observableFunction().toPromise()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants