简体   繁体   中英

How do I inject store dependencies with ngrx

I'm new to Angular, new to ngrx...

I have an injection problem which I'm sure is easy to overcome, if only I understood it, but I'm going round in circles at the moment, too many new concepts at once. It seems simple. when the app loads, I use a clientId/clientSecret to authenticate using clientauth.service and get a token returned. This token is kept in the store and used for any further requests to the API through api.service.

app.component.ts

this.store.dispatch(new ClientAuthActions.ClientAuthLoginRequest({ clientId: environment.clientId, clientSecret: environment.clientSecret }));

clientauth.effect.ts

constructor(
    private actions$: Actions,
    protected authService: ClientAuthService,
  ) {}

@Effect()
  login$ = this.actions$.pipe(
    ofType(clientauthActions.ClientAuthActionTypes.ClientAuthLoginRequest),
    switchMap((user: ClientAuthUser) => {
      return this.authService.login(user)
      .pipe(
        map((token: ClientAuthToken) => {
          return new clientauthActions.ClientAuthLoginSuccess(token);

        }),
        catchError(error => of(new clientauthActions.ClientAuthLoginFailure({error}))) //TODO, handle the error
      )
    })
  );
}

clientauth.service.ts

@Injectable()
export class ClientAuthService {
  constructor(
    protected apiService: ApiService,
  ) {
  }

  login(user: ClientAuthUser) {
.....
   return this.apiService.postClientLogin(user);
  }

api.service.ts

@Injectable()
export class ApiService {
  constructor(
    protected httpClient: HttpClient,
    protected store: fromClientAuth.State,
    ) {
  }


  getHttpHeaders(): HttpHeaders {

    const headers = new HttpHeaders({
      'Content-Type': 'application/json',
    });

    if (this.store.token) {
     return headers.append('Authorization', `Bearer ${this.store.token.accessToken}`);
    }

    return headers;
  }

  postClientLogin(...);

But there is something wrong with my dependency injection and I was getting the error: Error: Can't resolve all parameters for ApiService: ([object Object], ?).

I've tried adding the following to my app.module.ts, but I still get the same, and I'm obviously missing something here.

import * as fromClientAuth from './store/reducers/clientauth.reducer';

export const CLIENTAUTH_REDUCER_TOKEN = new InjectionToken<
  ActionReducerMap<fromClientAuth.State>
>('ClientAuth Reducers');

export function getReducers(): ActionReducerMap<fromClientAuth.State> {
  // map of reducers (I guess something is missing here, but I don't know how to complete it)
  return {}
}

@NgModule({
...
imports:[
...
    StoreModule.forRoot(reducers, {
      metaReducers, 
      runtimeChecks: {
        strictStateImmutability: true,
        strictActionImmutability: true,
      }
    }),
    StoreModule.forFeature(fromClientAuth.featureKey, CLIENTAUTH_REDUCER_TOKEN),
    EffectsModule.forRoot([AppEffects, ClientAuthEffects]),
],
providers: [
    ApiService,
    ClientAuthService,
    {
      provide: CLIENTAUTH_REDUCER_TOKEN,
      useFactory: getReducers,
    },
  ],
})

But I still get the same error. Could someone please point me in the right direction?

Thanks

export class ApiService {
constructor(
    protected httpClient: HttpClient,
    protected store: fromClientAuth.State  // <=
    ) {
  }

the comma on that line makes it assume that u have 3 parameters, and it cant identify the 3rd one.

You should inject the Store and not directly your State model.

So replacing protected store: fromClientAuth.State by protected store: Store<fromClientAuth.State> should solve at least a first issue.

@Injectable()
export class ApiService {
  constructor(
    protected httpClient: HttpClient,
    protected store: Store<fromClientAuth.State>,
    ) {
  }

PS: you can leave a comma at the end of last argument of a function.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM