In Angular 1.x, UI-Router was my primary tool for this. By returning a promise for "resolve" values, the router would simply wait for the promise to complete before rendering directives.
Alternately, in Angular 1.x, a null object will not crash a template - so if I don't mind a temporarily incomplete render, I can just use $digest
to render after the promise.then()
populates an initially empty model object.
Of the two approaches, if possible I'd prefer to wait to load the view, and cancel route navigation if the resource cannot be loaded. This saves me the work of "un-navigating". EDIT: Note this specifically means this question requests an Angular 2 futures-compatible or best-practice method to do this, and asks to avoid the "Elvis operator" if possible! Thus, I did not select that answer.
However, neither of these two methods work in Angular 2.0. Surely there is a standard solution planned or available for this. Does anyone know what it is?
@Component() {
template: '{{cats.captchans.funniest}}'
}
export class CatsComponent {
public cats: CatsModel;
ngOnInit () {
this._http.get('/api/v1/cats').subscribe(response => cats = response.json());
}
}
The following question may reflect the same issue: Angular 2 render template after the PROMISE with data is loaded . Note that question has no code or accepted answer in it.
Try
{{model?.person.name}}
this should wait for model to not beundefined
and then render.Angular 2 refers to this
?.
syntax as the Elvis operator. Reference to it in the documentation is hard to find so here is a copy of it in case they change/move it:Implement the
routerOnActivate
in your@Component
and return your promise:https://angular.io/docs/ts/latest/api/router/OnActivate-interface.html
EDIT: This explicitly does NOT work, although the current documentation can be a little hard to interpret on this topic. See Brandon's first comment here for more information: https://github.com/angular/angular/issues/6611
EDIT: The related information on the otherwise-usually-accurate Auth0 site is not correct: https://auth0.com/blog/2016/01/25/angular-2-series-part-4-component-router-in-depth/
EDIT: The angular team is planning a @Resolve decorator for this purpose.
The package
@angular/router
has theResolve
property for routes. So you can easily resolve data before rendering a route view.See: https://angular.io/docs/ts/latest/api/router/index/Resolve-interface.html
Example from docs as of today, August 28, 2017:
Now your route will not be activated until the data has been resolved and returned.
Accessing Resolved Data In Your Component
To access the resolved data from within your component at runtime, there are two methods. So depending on your needs, you can use either:
route.snapshot.paramMap
which returns a string, or theroute.paramMap
which returns an Observable you can.subscribe()
to.Example:
I hope that helps.
A nice solution that I've found is to do on UI something like:
Only when:
vendorServicePricing
,quantityPricing
andservice
are loaded the page is rendered.i'm using Angular 6 with Universal add-on I have read the answers specially the second one. But I did not get the point yet. I have a resolver that calls and HttpClient XHR request and send to component and the component on ngOnInit will bind data to the view. But the problem is in the view source mode, there is no data from the XHR response which is displayed in view.
EDIT: The angular team has released the @Resolve decorator. It still needs some clarification, in how it works, but until then I'll take someone else's related answer here, and provide links to other sources:
EDIT: This answer works for Angular 2 BETA only. Router is not released for Angular 2 RC as of this edit. Instead, when using Angular 2 RC, replace references to
router
withrouter-deprecated
to continue using the beta router.The Angular2-future way to implement this will be via the @Resolve decorator. Until then, the closest facsimile is
CanActivate
Component decorator, per Brandon Roberts. see https://github.com/angular/angular/issues/6611Although beta 0 doesn't support providing resolved values to the Component, it's planned, and there is also a workaround described here: Using Resolve In Angular2 Routes
A beta 1 example can be found here: http://run.plnkr.co/BAqA98lphi4rQZAd/#/resolved . It uses a very similar workaround, but slightly more accurately uses the
RouteData
object rather thanRouteParams
.Also, note that there is also an example workaround for accessing nested/parent route "resolved" values as well, and other features you expect if you've used 1.x UI-Router.
Note you'll also need to manually inject any services you need to accomplish this, since the Angular Injector hierarchy is not currently available in the CanActivate decorator. Simply importing an Injector will create a new injector instance, without access to the providers from
bootstrap()
, so you'll probably want to store an application-wide copy of the bootstrapped injector. Brandon's second Plunk link on this page is a good starting point: https://github.com/angular/angular/issues/4112