I'm not sure how to continue troubleshooting this ts2345 error and could use some help with understanding its cause.
Error Detail
Argument of type '(source$: Observable) => Observable' is not assignable to parameter of type 'OperatorFunction'.
Types of parameters 'source$' and 'source' are incompatible.
import("c:/Users/Flignats/Documents/GitHub/reqloot/node_modules/rxjs/internal/Observable").Observable' is not assignable to type 'import("c:/Users/Flignats/Documents/GitHub/reqloot/node_modules/rxjs/internal/Observable").Observable'.
Property 'user' is missing in type 'import("c:/Users/Flignats/Documents/GitHub/reqloot/src/app/modules/guilds/guilds.state").State' but required in type 'import("c:/Users/Flignats/Documents/GitHub/reqloot/src/app/modules/user/user.state").State'.ts(2345)
user.state.ts(19, 3): 'user' is declared here.
This is my effect file in the 'guilds' feature
guilds.effects.ts
import { IPrivateGuildDetails } from './guilds.model';
import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { select, Store } from '@ngrx/store';
import { ROUTER_NAVIGATION, RouterNavigationAction } from '@ngrx/router-store';
import { Actions, ofType, createEffect } from '@ngrx/effects';
import { of } from 'rxjs';
import {
map,
mergeMap,
catchError,
withLatestFrom,
switchMap,
tap,
filter
} from 'rxjs/operators';
// Core
import * as fromCore from '../../core';
import * as fromAuth from '../../core/auth/auth.selectors';
import * as fromUser from '../user/user.selectors';
// Key
export const GUILDS_KEY = 'GUILDS';
// State
import { State, selectGuilds } from './guilds.state';
// Actions
import {
createGuild,
createGuildSuccess,
createGuildFailure,
loadPublicGuilds,
loadPublicGuildsSuccess,
loadPublicGuildsFailure,
loadTriggerStatusCreateGuild,
loadTriggerStatusCreateGuildFailure,
loadTriggerStatusCreateGuildSuccess,
selectPublicGuild,
loadPublicGuild,
loadPublicGuildSuccess,
loadPublicGuildFailure,
loadMyGuild,
loadMyGuildSuccess,
loadMyGuildFailure
} from './guilds.actions';
@Injectable()
export class GuildsEffects {
loadMyGuild$ = createEffect(() =>
this.actions$.pipe(
ofType(loadMyGuild),
withLatestFrom(this.store.pipe(select(fromUser.selectUserAccountDetails))),
switchMap(([action, user]) =>
this.afs.loadMyGuild(user).pipe(
map((result: IPrivateGuildDetails) => loadMyGuildSuccess({ myGuild: result })),
catchError(error => of(loadMyGuildFailure({ error })))
)
)
)
);
loadTriggerStatusCreateGuild$ = createEffect(() =>
this.actions$.pipe(
ofType(loadTriggerStatusCreateGuild),
withLatestFrom(this.store.pipe(select(fromAuth.selectUid))),
mergeMap(([action, uid]) =>
this.afs.getTriggerStatusCreateNewGuild(uid).pipe(
map(triggerStatus =>
loadTriggerStatusCreateGuildSuccess({ triggerStatus })
),
catchError(error =>
of(loadTriggerStatusCreateGuildFailure({ error }))
)
)
)
)
);
constructor(
private actions$: Actions,
private afs: fromCore.FirestoreService,
private localStorageService: fromCore.LocalStorageService,
private router: Router,
private store: Store<State>
) {}
}
guilds.state.ts
import { ActionReducerMap, createFeatureSelector } from '@ngrx/store';
import { AppState } from '@app/core';
import { guildsReducer } from './guilds.reducer';
import { GuildsStateDetails } from './guilds.model';
export const FEATURE_NAME = 'guilds';
export interface GuildsState {
state: GuildsStateDetails;
};
export const reducers: ActionReducerMap<GuildsState> = {
state: guildsReducer
};
export const selectGuilds = createFeatureSelector<State, GuildsState>(FEATURE_NAME);
export interface State extends AppState {
guilds: GuildsState;
};
The error is produced in the loadMyGuild$
withLatestFrom select fn
The loadTriggerStatusCreateGuild$
effect is using a select from the core module and it does not produce an error.
If I update the loadMyGuild$
withLatestFrom selector with a selector from the Guilds
module, i.e. selectGuilds
there is no error.
I'm unsure what could be different in the User
feature module that is causing this error when trying to use its selectors in the Guilds
feature module.
user.state.ts
import { ActionReducerMap, createFeatureSelector } from '@ngrx/store';
import { AppState } from '@app/core';
import { userReducer } from './user.reducer';
import { UserStateDetails } from './user.model';
export const FEATURE_NAME = 'user';
export const selectUser = createFeatureSelector<State, UserState>(FEATURE_NAME);
export const reducers: ActionReducerMap<UserState> = {
state: userReducer
};
export interface UserState {
state: UserStateDetails;
}
export interface State extends AppState {
user: UserState;
}
user.selectors.ts
import { createSelector } from '@ngrx/store';
import { UserState, selectUser } from './user.state';
export const selectActiveUser = createSelector(
selectUser,
(state: UserState) => state.state
);
export const selectUserAccountDetails = createSelector(
selectUser,
(state: UserState) => state.state.account
);
export const selectUserLoading = createSelector(
selectUser,
(state: UserState) => state.state.loading
);
export const selectUserError = createSelector(
selectUser,
(state: UserState) => state.state.error
);
user.model.ts
import { HttpErrorResponse } from '@angular/common/http';
import { Timestamp } from '@firebase/firestore-types';
export interface IUser {
applixir?: {
lastWatchedAt?: Timestamp;
staminaLastGiven?: Timestamp;
totalAdsWatched?: number;
totalStaminaCollected?: number;
currentAdsTrackedCount: number;
};
balance: {
claimed: number;
unclaimed: number;
};
createdAt: Timestamp;
displayName?: string;
email: string;
fcmTokens?: { [token: string]: true };
guildDetails?: {
attacks: { [key: string]: number };
boosts: { [key: string]: { [key: string]: number } };
guildId: string;
guildTokensCollected: number;
guildTokensCollectedCount: number;
shield: { [key: string]: number };
};
referredBy?: string;
referredAt?: Timestamp;
stamina: number;
staminaLastGiven?: Timestamp;
subscriberStamina?: number;
subscriberStaminaLastGiven?: Timestamp;
uid: string;
updatedAt?: Timestamp;
}
export interface UserStateDetails {
error: HttpErrorResponse | string;
loading: boolean;
account: IUser;
}
You are using wrong store - you injected in your effects Store<State>
where State
is guild state and of course user selectors won't work on it. You need to inject Store with User state and use it instead.