[英]NgRx: Get data from store but it's undefined
dear Stackoverflow Community. 亲爱的Stackoverflow社区。
I'm new in NgRx and trying to find out how does it works. 我是NgRx的新手,试图找出它是如何工作的。 I create an app - simple Shop List based on Angular 6, Firebase and NgRx.
我创建了一个应用-基于Angular 6,Firebase和NgRx的简单商店清单。
I added a couple of items in collection called Product
and trying to fetch them via ngrx patterns. 我在集合中添加了几个名为
Product
的项目,并尝试通过ngrx模式获取它们。 Seems I did all good - I have fetched items as payload in GET_PRODUCTS_SUCCESS
but I can't put them into the view to display, products are undefined. 似乎我做得很好-我已经在
GET_PRODUCTS_SUCCESS
获取了项目作为有效载荷,但是我无法将它们放入视图中显示,产品未定义。 I tried to do in two ways: 我尝试通过两种方式进行操作:
this.store.select(getProducts).subscribe(products => {
console.log('products', products); // undefined
});
and 和
this.products = this.store.select(getProducts); // Store
In second way I just get a whole Store... Code below. 第二种方式,我只是得到了整个商店...下面的代码。
product.actions.ts product.actions.ts
import { Action } from '@ngrx/store';
import { Product } from '../../models/product.model';
export const GET_PRODUCTS = 'Get_products';
export const GET_PRODUCTS_SUCCESS = 'Get_products_success';
export class GetProducts implements Action {
readonly type = GET_PRODUCTS;
constructor(public payload = '') {}
}
export class GetProductsSuccess implements Action {
readonly type = GET_PRODUCTS_SUCCESS;
constructor(public payload?: Product[]) {}
}
export type Actions = GetProducts | GetProductsSuccess;
product.reducer.ts product.reducer.ts
import { Product } from '../../models/product.model';
import * as productAction from './products.action';
export interface State {
products: Product[];
loading: boolean;
}
export const initialState: State = {
products: [],
loading: false,
};
export function ProductsReducer(state: State = initialState, action: productAction.Actions) {
switch (action.type) {
case productAction.GET_PRODUCTS:
return {...state, loading: true};
case productAction.GET_PRODUCTS_SUCCESS:
const test = {...state, products: action.payload, loading: false};
console.log("test", test);
return test;
default:
return state;
}
}
product.effects.ts product.effects.ts
import { Injectable } from '@angular/core';
import { Action } from '@ngrx/store';
import { Effect, Actions } from '@ngrx/effects';
import { AngularFirestore } from '@angular/fire/firestore';
import { Product } from '../../models/product.model';
import * as productAction from './products.action';
import { Observable, of } from 'rxjs';
import { switchMap, map, mergeMap } from 'rxjs/operators';
@Injectable()
export class ProductEffects {
constructor(private actions$: Actions, private db: AngularFirestore) {}
@Effect()
getProducts: Observable<Action> = this.actions$
.ofType(productAction.GET_PRODUCTS).pipe(
switchMap(() => {
return this.db.collection<Product>('products').valueChanges()
.pipe(
map((payload) => {
return {
type: 'Get_products_success',
payload: payload
};
})
);
})
);
}
product.selector.ts product.selector.ts
import { createSelector } from '@ngrx/store';
import { State } from './products.reducer';
import { Product } from '../../models/product.model';
export function getState(state: State): State {
return state;
}
export function fetchProducts(state: State): Product[] {
return state.products;
}
export const getProducts = createSelector(getState, fetchProducts);
list.component.ts - get and display all products list.component.ts-获取并显示所有产品
import { Component, OnInit } from '@angular/core';
import { Store } from '@ngrx/store';
import { Product } from '../../models/product.model';
import * as productActions from '../../store/products/products.action';
import { State } from '../../store/products/products.reducer';
import { getProducts } from '../../store/products/products.selector';
import { Observable } from 'rxjs';
@Component({
selector: 'app-list',
templateUrl: './list.component.html',
styleUrls: ['./list.component.scss']
})
export class ListComponent implements OnInit {
products: Observable<Product[]>;
constructor(private store: Store<State>) {}
ngOnInit() {
this.store.dispatch(new productActions.GetProducts);
this.store.select(getProducts).subscribe(products => {
console.log('products', products);
});
}
}
If you noticed that I'm doing something wrong - don't shy to tell me. 如果您发现我做错了-不要害羞告诉我。 I really need your help.
我真的需要你的帮助。 Thanks.
谢谢。
I found out 我发现
I looked that how else I can make a request my data from store. 我看着我还能如何从存储请求数据。 I found one way, in context of my app it looks like:
我发现一种方法,在我的应用程序中,它看起来像:
this.store.select(state => state).subscribe(data => {
console.log('data', data);
});
And I get in console the object: 然后进入控制台对象:
{ message: { Products: Array[3], loading: false } }
What does this message mean? 此消息是什么意思? I made a global search and saw that I implemented my reducer in
app.module.ts
as: 我进行了全局搜索,发现我在
app.module.ts
实现了我的reducer为:
StoreModule.forRoot({ message: ProductReducer }),
So I created a index.ts
in reducers folder and export a reducer bellow: 因此,我在reducers文件夹中创建了
index.ts
并导出了一个reducer的波纹管:
import { ActionReducerMap } from '@ngrx/store';
import * as fromProducts from './products.reducer';
export interface AppState {
products: fromProducts.ProductState;
}
export const reducers: ActionReducerMap<AppState> = {
products: fromProducts.productsReducer
};
And now in app.module.ts
it imports as: 现在在
app.module.ts
它导入为:
StoreModule.forRoot(reducers),
and now this code is working well: 现在这段代码运行良好:
this.store.select(getProducts).subscribe(products => {
console.log('products', products);
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.