I want to print history of products. I have an id of product in ActivatedRoute.params. In ngOnInit method I have to get all history of product and assign to variable. Then I want to map product to productHistory, because I want to have last version with history toghether. But the problem is with getting history. Method to getting history return Promise and I cannot get length of productsHistory when I use this property and I get undefined. How can I get this property after loading from service?
I want to execute method after execution getHistory().
My code:
ProductService.ts:
import { Injectable } from '@angular/core';
import { Headers, Http } from '@angular/http';
import 'rxjs/add/operator/toPromise';
// rest imports
@Injectable()
export class ProductService {
// URL to web api
private projectsUrl = 'http://localhost:8080/products';
private headers = new Headers({'Content-Type': 'application/json'});
constructor(private http: Http) {}
getHistory(id: number): Promise<ProductHistory[]> {
const url = `${this.projectsUrl}/projectId/${id}`;
return this.http.get(url)
.toPromise()
.then(response => response.json() as ProductHistory[])
.catch(this.handleError);
}
handleError() {
//...
// implementation is irrelevant
}
}
ProductHistoryComponent.ts:
import { Component, Input, OnInit } from '@angular/core';
import { ActivatedRoute, Params } from '@angular/router';
import { Location } from '@angular/mon';
import { ProductService } from './product.service';
import { ProductHistory } from './product-history';
import { Product } from './model/product';
import 'rxjs/add/operator/switchMap';
@Component({
selector: 'product-history',
templateUrl: './product-historyponent.html',
styleUrls: [ './product-historyponent.css' ]
})
export class ProductHistoryComponent implements OnInit {
auditProducts: ProductHistory[] = new Array<ProductHistory[]>();
selectedProduct: ProductHistory;
constructor(
private route: ActivatedRoute,
private location: Location,
private productService: ProductService
) {}
ngOnInit(): void {
let id: number = this.route.snapshot.params['id'];
this.productService.getHistory(id)
.then(history => this.historyProducts = history);
this.productService.getProduct(id)
.then(product => {
let lastVersion: ProductHistory = this.createLastVersion(product);
this.auditProducts.push(lastVersion);
});
}
onSelect(ProductHistory: ProductHistory): void {
this.selectedProduct = ProductHistory;
thispare(this.selectedProduct);
}
goBack(): void {
this.location.back();
}
pare(history: ProductHistory): void {
let previous: ProductHistory;
if (history.changeNumber != null && history.changeNumber > 1) {
previous = this.historyProducts[history.changeNumber - 2];
if (typeof previous != 'undefined') {
this.setPreviousDiffsFalse(previous);
if (previous.name !== history.name) {
history.nameDiff = true;
}
if (previous.price !== history.price) {
history.priceDiff = true;
}
}
}
}
createLastVersion(product: Product): ProductHistory {
let lastVersionProduct: ProductHistory = new ProductHistory();
lastVersionProduct.id = this.historyProducts.length + 1;
lastVersionProduct.name = product.name;
lastVersionProduct.price = product.price;
lastVersionProduct.changeNumber = this.historyProducts[this.historyProducts.length - 1].changeNumber + 1;
return lastVersionProduct;
}
setPreviousDiffsFalse(previous: ProductHistory): void {
previous.nameDiff = false;
previous.priceDiff = false;
}
}
I want to print history of products. I have an id of product in ActivatedRoute.params. In ngOnInit method I have to get all history of product and assign to variable. Then I want to map product to productHistory, because I want to have last version with history toghether. But the problem is with getting history. Method to getting history return Promise and I cannot get length of productsHistory when I use this property and I get undefined. How can I get this property after loading from service?
I want to execute method after execution getHistory().
My code:
ProductService.ts:
import { Injectable } from '@angular/core';
import { Headers, Http } from '@angular/http';
import 'rxjs/add/operator/toPromise';
// rest imports
@Injectable()
export class ProductService {
// URL to web api
private projectsUrl = 'http://localhost:8080/products';
private headers = new Headers({'Content-Type': 'application/json'});
constructor(private http: Http) {}
getHistory(id: number): Promise<ProductHistory[]> {
const url = `${this.projectsUrl}/projectId/${id}`;
return this.http.get(url)
.toPromise()
.then(response => response.json() as ProductHistory[])
.catch(this.handleError);
}
handleError() {
//...
// implementation is irrelevant
}
}
ProductHistoryComponent.ts:
import { Component, Input, OnInit } from '@angular/core';
import { ActivatedRoute, Params } from '@angular/router';
import { Location } from '@angular/mon';
import { ProductService } from './product.service';
import { ProductHistory } from './product-history';
import { Product } from './model/product';
import 'rxjs/add/operator/switchMap';
@Component({
selector: 'product-history',
templateUrl: './product-history.ponent.html',
styleUrls: [ './product-history.ponent.css' ]
})
export class ProductHistoryComponent implements OnInit {
auditProducts: ProductHistory[] = new Array<ProductHistory[]>();
selectedProduct: ProductHistory;
constructor(
private route: ActivatedRoute,
private location: Location,
private productService: ProductService
) {}
ngOnInit(): void {
let id: number = this.route.snapshot.params['id'];
this.productService.getHistory(id)
.then(history => this.historyProducts = history);
this.productService.getProduct(id)
.then(product => {
let lastVersion: ProductHistory = this.createLastVersion(product);
this.auditProducts.push(lastVersion);
});
}
onSelect(ProductHistory: ProductHistory): void {
this.selectedProduct = ProductHistory;
this.pare(this.selectedProduct);
}
goBack(): void {
this.location.back();
}
pare(history: ProductHistory): void {
let previous: ProductHistory;
if (history.changeNumber != null && history.changeNumber > 1) {
previous = this.historyProducts[history.changeNumber - 2];
if (typeof previous != 'undefined') {
this.setPreviousDiffsFalse(previous);
if (previous.name !== history.name) {
history.nameDiff = true;
}
if (previous.price !== history.price) {
history.priceDiff = true;
}
}
}
}
createLastVersion(product: Product): ProductHistory {
let lastVersionProduct: ProductHistory = new ProductHistory();
lastVersionProduct.id = this.historyProducts.length + 1;
lastVersionProduct.name = product.name;
lastVersionProduct.price = product.price;
lastVersionProduct.changeNumber = this.historyProducts[this.historyProducts.length - 1].changeNumber + 1;
return lastVersionProduct;
}
setPreviousDiffsFalse(previous: ProductHistory): void {
previous.nameDiff = false;
previous.priceDiff = false;
}
}
Share
Improve this question
edited Jul 5, 2017 at 15:16
Dinistro
5,7301 gold badge32 silver badges39 bronze badges
asked Jul 5, 2017 at 14:48
useruser
4,85017 gold badges64 silver badges83 bronze badges
1
- 4 You cannot get a value synchronously from a promise any more than you get an apple from an orange. – user663031 Commented Jul 5, 2017 at 14:57
2 Answers
Reset to default 2You can't run it synchronously, you have to wait for each promise to return a result before you can do something with that result. The normal way to do this is to nest code inside then
blocks when using promises. Alternatively you can also use async/await
with the latest version of typescript and you only have to change your ponent
code as you are already returning the Promise
type from your service. This makes code easier to read (IMO) although the emitted javascript code will still use function/callback nesting (unless you are targeting es7 I believe, maybe someone will correct or confirm this).
// note the use of async and await which gives the appearance of synchronous execution
async ngOnInit() {
let id: number = this.route.snapshot.params['id'];
const history = await this.productService.getHistory(id);
this.historyProducts = history;
const product = await this.productService.getProduct(id);
let lastVersion: ProductHistory = this.createLastVersion(product);
this.auditProducts.push(lastVersion);
}
I would suggest using observables instead of promises ... but to answer your question, you just need to perform the second request after the first is received. Something like this:
ngOnInit(): void {
let id: number = this.route.snapshot.params['id'];
this.productService.getHistory(id)
.then(history => {
this.historyProducts = history);
this.productService.getProduct(id)
.then(product => {
let lastVersion: ProductHistory = this.createLastVersion(product);
this.auditProducts.push(lastVersion);
});
}
}
I just moved the second request within the then of the first request. NOTE: I did not syntax check this.
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744754157a4591778.html
评论列表(0条)