2016-08-18 2 views
1

Ich versuche zu lernen @ ngrx/Shop mit Angular 2 - RC4. Ich habe einen Dienst, den ich von meiner Komponente aus anrufe, und ich versuche nur, eine Liste von Fahrzeugen zu loggen, wenn sich diese ändert.@ ngrx/Shop mit Angular 2: Kann nicht lesen Eigenschaft von undefined

Fahrzeug

export interface Vehicle { 
    ...stuff... 
} 

Fahrzeug Reducer

import { Vehicle } from '../models'; 

export interface VehiclesState { 
    vins: string[]; 
    vehicles: { [vin: string]: Vehicle }; 
} 

const initialState: VehiclesState = { 
    vins: [], 
    vehicles: {} 
} 

export const vehicles = (state: any = initialState, {type, payload}) => { 
    switch (type) { 
    case 'LOAD_VEHICLES': 
     const vehicles: Vehicle[] = payload; 
     const newVehicles = vehicles.filter(vehicle => !state.vehicles[vehicle.vin]); 

     const newVehicleVins = newVehicles.map(vehicle => vehicle.vin); 
     const newVehiclesList = newVehicles.reduce((vehicles: { [vin: string]: Vehicle }, vehicle: Vehicle) => { 
     return mergeObjects(vehicles, { 
      [vehicle.vin]: vehicle 
     }); 
     }, {}); 

     return { 
     vins: [...state.vins, ...newVehicleVins], 
     vehicles: mergeObjects({}, state.vehicles, newVehiclesList) 
     } 
    } 
} 

main.ts

import { bootstrap } from '@angular/platform-browser-dynamic'; 
import { enableProdMode } from '@angular/core'; 
import { HTTP_PROVIDERS } from '@angular/http'; 
import { provideStore } from '@ngrx/store' 

import { AppComponent, environment } from './app/'; 
import { vehicles } from './app/shared/reducers/vehicles' 

if (environment.production) { 
    enableProdMode(); 
} 

bootstrap(AppComponent, 
    [ 
    HTTP_PROVIDERS, 
    provideStore(vehicles, { 
     vins: [], 
     vehicles: {} 
    }) 
    ] 
); 

VehiclesService

import {Http, Headers} from '@angular/http'; 
import {Injectable} from '@angular/core'; 
import {Store} from '@ngrx/store'; 
import {Observable} from "rxjs/Observable"; 
import 'rxjs/add/operator/map'; 

import {Vehicle} from '../models/vehicle.model'; 

const BASE_URL = 'http://localhost:3000/vehicles/'; 
const HEADER = { headers: new Headers({ 'Content-Type': 'application/json' }) }; 

@Injectable() 
export class VehiclesService { 
    vehicles: Observable<Array<Vehicle>>; 

    constructor(private http: Http, private store: Store<Vehicle[]>) { 
    this.vehicles = this.store.select('vehicles'); 
    } 

    loadVehicles() { 
    this.http.get(BASE_URL) 
     .map(res => res.json()) 
     .map(payload => ({ type: 'LOAD_VEHICLES', payload: payload })) 
     .subscribe(action => this.store.dispatch(action)); 
    } 
} 

AppComponent

import { Component, OnInit, Input } from '@angular/core'; 
import { Observable } from "rxjs/Observable"; 
import { Store } from '@ngrx/store'; 

import { Vehicle, VehiclesService } from './shared'; 

@Component({ 
    moduleId: module.id, 
    selector: 'app-root', 
    templateUrl: 'app.component.html', 
    styleUrls: ['app.component.css'], 
    providers: [VehiclesService] 
}) 
export class AppComponent implements OnInit{ 
    title = 'app works!'; 

    vehicles: Observable<Vehicle[]>; 

    constructor(private vehiclesService: VehiclesService) { 
    this.vehicles = vehiclesService.vehicles; 

    vehiclesService.loadVehicles(); 
    } 

    ngOnInit() { 
    console.log(this.vehicles) 
    this.vehicles.subscribe(vehicles => console.log(vehicles)); 
    } 
} 

Aber wenn es läuft, bekomme ich eine Typeerror TypeError: Cannot read property 'vehicles' of undefined

Der erste console.log a Store-Objekt zurückgibt, aber das Abonnement scheint zum Scheitern verurteilt .

Irgendeine Idee, was ich falsch mache?

Antwort

2

Sie benötigen provideStore({vehicles: vehicles}) Ihre provideStore sein zu ändern.

+1

auf. Das hat den Trick gemacht. Es gab ein paar andere Probleme, aber das war die Hauptsache. Danke, mein Herr! –

0

Es gibt nicht genug Informationen: Vorlage app.component.ts fehlt in der Frage.

Überprüfen Sie jedoch, wie Sie in Ihrer Vorlage auf das Element vehicles zugreifen. Versuchen Sie den Operator ?. anstelle von .. Etwas wie:

{{ yourObject?.vehicles }} 
+0

Ich greife nicht in der Vorlage darauf zu. Der Fehler tritt in der zweiten Zeile der "ngOnInit" -Funktion in AppComponent –

1

In meinem Fall war der Fehler die Verwendung von verschiedenen Namen in dem Reduktions Objekt und die Schnittstelle:

import { LeaderboardParticipant } from './...'; 
import * as fromLeaderboard from './...'; 

export interface IState { 
    leaderboard: fromLeaderboard.IState; 
} 

export const reducers = { 
    leaderboard: fromLeaderboard.reducer // I used to have 'search' instead of 'leaderboard' 
}; 

export function selectChallengeId(state: IState): string { 
    return state.leaderboard.challengeId; 
} 

export function selectFilterTerms(state: IState): string { 
    return state.leaderboard.filterTerms; 
} 
0

Wenn Sie Ihren Store (Store) erklären, ich glaube, der richtige Weg ist:

constructor(private http: Http, private store: Store<VehicleState>) 
Verwandte Themen