2017-01-24 1 views
9

Я довольно новый в Angular2/TypeScript, поэтому, пожалуйста, извините меня, если я делаю какую-то глупую ошибку. То, что я пытаюсь сделать, это выбрать «Выбрать». Я заполняю данные, используя службу, которая возвращает мне массив JSON.Тип 'Observable <any>' не подлежит назначению type '[]'

Вот мой код:

product-maintenance.component.ts 

import { Component, OnInit} from '@angular/core'; 
import { ProductMaintenanceService } from '../../_services/product-maintenance.service'; 
import { ModuleConst } from '../../../data/const'; 
import { Product } from './product-types'; 
import { Products } from './products'; 

@Component({ 
    selector: 'app-product-maintenance', 
    templateUrl: './product-maintenance.component.html', 
    styleUrls: ['./product-maintenance.component.css'] 
}) 

export class ProductMaintenanceComponent implements OnInit { 
selectedProduct: Product = new Product(0, 'Insurance'); 
products: Product[]; 
productList: Products[]; 

constructor(private productService: ProductMaintenanceService) { 

} 

    ngOnInit() { 
     // Dropdown list 
     this.products = this.productService.getProductTypeList(); 
    } 
    // Populate data using onSelect method 
    onSelect(typeid) { 
     this.productList = this.productService.getProducts() 
     .filter((item)=>item.ptypeid == typeid); 
    } 
} 

product-type.ts (используется для для заполнения выпадающего списка):

export class Product { 
    constructor(
    public ptypeid: number, 
    public name: string 
) { } 
} 

products.ts (используется для заселить данные службы):

export class Products { 
    constructor(
     public id: number, 
     public ptypeid: number, 
     public name: string, 
     public currency: string, 
     public state: string, 
     public riskRating: number, 
     public clientSegment: string, 
     public aiStatus: string, 
     public premiumType: string, 
     public tenure: number 
) { } 
} 

product-maintenance.service.ts:

import { Injectable, Inject } from '@angular/core'; 
import { Http, Headers, RequestOptions, Response } from '@angular/http'; 
import { Observable } from 'rxjs/Rx'; 
import 'rxjs/add/operator/map'; 
import 'rxjs/add/operator/filter'; 
import { APP_CONFIG, IAppConfig } from '../app.config'; 
import { Products } from './products'; 
import { Product } from './product-types'; 

@Injectable() 
export class ProductMaintenanceService { 
    result: Array<Object>; 
    constructor(
     @Inject(APP_CONFIG) private config: IAppConfig, 
     private http: Http 
    ) { } 

    private productURL = 'data/productList.json'; 

    // Get product list 
    getProducts() : Observable<any> { 
    // ...using get request 
    return this.http.get(this.productURL) 
     // ...and calling .json() on the response to return data 
     .map((response: Response) => { 
      console.log(response); 
      return response.json(); 
     }); 
    } 


    getProductTypeList() { 
     return [ 
     new Product(1, 'Unit Trust'), 
     new Product(2, 'Insurance'), 
     new Product(3, 'Structured Deposit'), 
     new Product(4, 'Bonds'), 
     new Product(5, 'DCI'), 
     new Product(6, 'SP') 
     ]; 
    } 
} 

product-maintenance.component.html:

<table> 
<tr *ngFor="let item of productList"> 
       <td>{{ item.id }}</td> 
       <td>{{ item.name }}</td> 
       <td>{{ item.currency }}</td> 
       <td>{{ item.state }}</td> 
       <td>{{ item.riskRating }}</td> 
       <td>{{ item.clientSegment }}</td> 
       <td>{{ item.aiStatus }}</td> 
       <td>{{ item.premiumType }}</td> 
       <td>{{ item.tenure }}</td> 
      </tr> 
</table> 

productList.json:

[ 
     { 
     "ptypeid": 1, 
     "id": 1, 
     "name": "Unit Trust 1", 
     "currency": "SGD", 
     "state": "Active", 
     "riskRating": 1, 
     "clientSegment": "Retail/Premier", 
     "aiStatus": "No", 
     "premiumType": "Regular Premium", 
     "tenure": 5 
     }, 
     { 
     "ptypeid": 2, 
     "id": 2, 
     "name": "Unit Trust 2", 
     "currency": "SGD", 
     "state": "Active", 
     "riskRating": 3, 
     "clientSegment": "Retail/Premier", 
     "aiStatus": "No", 
     "premiumType": "Single/Lumpsum Premium", 
     "tenure": 10 
     } 
] 

Если я определяю мой getProducts(), как getProductTypeList() то это прекрасно заселение данные, на мой взгляд (Где, если я выбираю доверие единицы из выпадающего списка вниз, то он должен заполнить соответствующие данные). Но если я использую в качестве апи URL вместо этого он дает мне ошибку ниже:

Type 'Observable<any>' is not assignable to type 'Products[]'. Property 'length' is missing in type 'Observable<any>'

Я не понимаю, как решить эту ошибку. Может ли кто-нибудь помочь мне в этом. Заранее спасибо.

+0

вам удалось решить вашу проблему Observable? – wladyband

ответ

5

productList должно быть Product[] не Observable<any>. Так присвоить productList значение из getProducts подписки метод, в котором вы будете извлекать массив Product

onSelect(typeid) { 
    this.productService.getProducts() 
    .filter((item)=>item.ptypeid == typeid) 
    .subscribe((products) => { 
     this.productList = products; 
    }); 
} 
+0

Я до сих пор не могу его забрать. Даже он не может войти под этим .subscribe ((products) => { this.productList = products; }) – tutorialfeed

+0

@tutorialfeed вы все еще получаете ошибку времени компиляции? –

+0

ошибка исчезла, но я не получаю данные. – tutorialfeed

3

Изменить метод метод getProducts к

getProducts() : Observable<any> { 
    // ...using get request 
    let response = this.http.get(this.productURL) 
     // ...and calling .json() on the response to return data 
     .map((response: Response) => response.json()); 
    return response; 
} 
+0

Этот тоже не работает. – tutorialfeed

3

несколько проблем, сначала я заметил, что вы используете относительный URL для вашего запроса на получение. Это не сработает. У вас должен быть правильный URL-адрес, что означает что-то, начинающееся с http://.., даже если ваш api находится на localhost, вам нужно предоставить полный URL-адрес.

Во-вторых, запрос прибудете в порядке, но ваш вызов в компоненте должен выглядеть следующим образом:

this.productService.getProducts() 
    .subscribe(data => { 
    this.productList = data}) 

Поскольку вы делаете карту в вашем запросе, вам также необходимо подписаться на том, что, в противном случае вы не получат никаких результатов!

Стоит упомянуть также, так как это операция async, вы можете включить ngIf в свою таблицу, чтобы ваше приложение не выдавало ошибку в случае, если представление отображается до того, как данные прибыли, так что просто сделайте это:

<table *ngIf="productList"> 

Это должно прояснить ситуацию!

В качестве альтернативы, если вы не хотите, чтобы подписаться, вы можете сделать, как вы ранее делали:

this.products = this.productService.getProductTypeList(); 

, но тогда вы должны использовать async трубы в целях:

<tr *ngFor="let item of productList | async"> 

В в этом случае асинхронная трубка подписывается для вас :)

+0

В течение ограниченного времени, вот рабочий плункер с макетным бэкэндом: https://plnkr.co/edit/oxgy93cEFM5USf07xeIL?p=preview Не включил его в ответ, поскольку он использует насмешливый, и он не будет работать навсегда, но если вы сомневаетесь, вы можете проверить plunk и сравнить его с вашим кодом, и когда вы закончите, я думаю, что я удалю этот комментарий;) – Alex

+0

@tutorialfeed, это решение вам помогло? :) – Alex

Смежные вопросы