如何通过服务访问我的商店?

时间:2019-06-26 07:27:17

标签: angular ngrx

我最近使用NgRx来管理发送API请求。 我的API请求在服务中,我的效果使用此服务。非常经典。

@Injectable({
  providedIn: 'root'
})
export class MaterialService {
  private url = "materials";

  constructor(private http: HttpClient) { }

  getMaterials () {
    return this.http.get (this.url).pipe (
      catchError (this.handleError)
    );
  }

  handleError (error: HttpErrorResponse): Observable<never> {
    return throwError (error.message);
  }
}
@Injectable()
export class MaterialEffects {

  @Effect() loadMaterial$ = this.dataPersistence.fetch(
    MaterialActionTypes.LoadMaterial,
    {
      run: (action: LoadMaterial, state: MaterialPartialState) => {

        return this.materialService.getMaterials ().pipe (
          map (data => {
            return new MaterialLoaded(data);
          }),
//          catchError (error => of (new MaterialLoadError (error)))
        );
      },

      onError: (action: LoadMaterial, error) => {
        console.error('Error', error);
        return new MaterialLoadError(error);
      }
    }
  );
...

总体来说效果很好。我就是喜欢它:)

但是对于某些请求,我需要恢复一些ID以创建我的URL。这些ID主要是通用ID。例如,我们的客户ID。 https://my.example.com/perimeters/[PERIMETER_ID]/relationships/users

如何使用服务从商店中检索内容ID,创建URL并按预期返回我的Observable?

先谢谢您

1 个答案:

答案 0 :(得分:1)

将商店注入到效果类MaterialEffects中,并获取所需的值,然后将其作为参数传递到MaterialService中。

因此您的效果将如下所示:

@Injectable()
export class MaterialEffects {

    constructor(private store: Store<any>)

    @Effect() loadMaterial$ = this.dataPersistence.fetch(
        MaterialActionTypes.LoadMaterial,
        {
            run: (action: LoadMaterial, state: MaterialPartialState) => {

                return this.store.pipe(
                    select(x => x.perimiterId),
                    mergeMap((perimiterId) => {
                        materialService.getMaterials(perimiterId).pipe(
                            map(data => {
                                return new MaterialLoaded(data);
                            }),
                            // catchError (error => of (new MaterialLoadError (error)))
                        )
                    })
                )
            },

            onError: (action: LoadMaterial, error) => {
                console.error('Error', error);
                return new MaterialLoadError(error);
            }
        }
    );
...