D_Naish D_Naish - 3 months ago 62
AngularJS Question

@ngrx/store with Angular 2: Cannot read property of undefined

I'm trying to learn @ngrx/store with Angular 2 - RC4. I've got a service that I'm calling from my component, and I'm just trying to console log a list of vehicles whenever it changes.

Vehicle

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


Vehicle 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));
}
}


But when it runs, I get a TypeError
TypeError: Cannot read property 'vehicles' of undefined


The first console.log returns a Store object, but the subscription seems to fail.

Any idea what I'm doing wrong?

Answer

You need to change your provideStore to be provideStore({vehicles: vehicles}).

Comments