我有一个带有四个ngrx动作的Angular(2)应用程序:
问题是捕获ADVANCE的效果似乎在处理SUCCESS的reducer之前运行
这是效果代码:
@Effect() start$ = this.actions$
.ofType('START')
.map(toPayload)
.switchMap(input => doAsyncTask(input)
.map(result => ({type: 'SUCCESS', payload: result}))
.catch(error => ({type: 'ERROR', payload: error})));
@Effect() success$ = this.actions$
.ofType('SUCCESS')
.map(() => ({type: 'ADVANCE'}));
@Effect({dispatch: false}) advance$ = this.actions$
.ofType('ADVANCE')
.withLatestFrom(this.store$.select(state => state.route))
.map(action_route => action_route[1])
.do(route => this.router.navigate([route.foo.bar]));
Run Code Online (Sandbox Code Playgroud)
我得到的错误是Cannot read property 'bar' of null.该属性foo由处理SUCCESS的reducer设置.
如果我为SUCCESS效果添加一个延迟,那么一切都很好:
@Effect() success$ = this.actions$
.ofType('SUCCESS')
.delay(1)
.map(() => …Run Code Online (Sandbox Code Playgroud) 与ngrx/example-app类似,我正在构建一个界面,用户可以通过输入文本字符串来搜索某些内容.
我想用可选的param(query=search_string)更新url,这样当用户使用后退按钮返回搜索时,它们将返回已加载的相同搜索.(我也会为他们所在的页面做同样的事情)
用ngrx添加可选参数的适当方法是什么?
我想是BookEffects因为我们不想在去抖时间之前更新路线.但由于某种原因感觉不对......
[编辑]为了进一步扩展,当用户导航回搜索页面时,需要以某种方式引导搜索.所以我的想法也是修改FindBookPageComponent包括:
constructor(..., private route: ActivatedRoute) {
...
}
ngOnInit() {
let query = this.route.snapshot.params['query'];
if (query) {
this.store.dispatch(new book.SearchAction(query));
}
}
Run Code Online (Sandbox Code Playgroud)
这仍然觉得尴尬,因为之前的搜索结果显示,由于会有不自然的延迟debounce的SearchAction. 那么,这是否意味着我们还应该创建一个单独的搜索行动:ImmediateSearchAction?
我遇到的问题是我的应用程序没有调度某些操作或在调度操作时没有调用某些效果(请参阅从组件调度操作时未调用ngrx效果).
我想知道如何调试ngrx存储,动作和效果.
由于ngrx的打字稿来源在我的环境中不可用(似乎只有类型可用),还有其他方法可以知道商店和效果中发生了什么吗?
PS 似乎开发商店工具只允许查看减速器引起的变化.
我正在努力测试ngrx商店中的效果.在将ngrx更新为版本后,我发现改变方式,如何测试它.
import { hot, cold } from 'jasmine-marbles';
it('should work', () => {
actions = hot('--a-', { a: SomeAction });
const expected = cold('--b', { b: AnotherAction });
expect(effects.someSource$).toBeObservable(expected);
});
Run Code Online (Sandbox Code Playgroud)
不幸的是,我没有找到任何关于茉莉花弹珠的文件.任何人都可以解释一下冷热功能的第一个参数是什么意思吗?是否可以找到有关它的任何文档?
我正在尝试使用ngrx store + ng效果为我的应用编写登录流程.我已经设法编写它并且它在快乐的场景中工作,但是当用户向表单输入错误的值,以便服务器响应401时,下一次登录尝试没有效果.我已经读过,在使用observable时必须捕获异常以便不"破坏"流,但据我所知,我已经捕获了异常并且它现在仍在工作.
代码下面;
export class LoginComponent {
logged = new Observable<any>();
constructor(private store: Store<AppStore>) {
this.logged = store.select('login');
}
login(username: string, password: string){
let body = JSON.stringify({username, password});
this.store.dispatch({type: LoginActions.ATTEMPT_LOGIN, payload: body});
}
}
@Injectable()
export class LoginEffects {
constructor(
private actions: Actions,
private loginService: LoginService
) { }
@Effect() login = this.actions
.ofType(LoginActions.ATTEMPT_LOGIN)
.map(toPayload)
.switchMap(payload => this.loginService.attemptLogin(payload))
.map(response => new LoginActions.LoginSuccess(response))
.catch(error => of(new LoginActions.LoginFailed(error)));
@Effect() success = this.actions
.ofType(LoginActions.LOGIN_SUCCESS)
.map(toPayload)
.map(payload => localStorage.setItem(Global.TOKEN, payload))
.map(() => …Run Code Online (Sandbox Code Playgroud) 有一个简单的(Angular 4)路由守卫,它等待从后端加载一些数据:
@Injectable()
export class ContractsLoadedGuard implements CanActivate {
constructor(private store: Store<State>) { }
waitForData(): Observable<boolean> {
return this.store.select(state => state.contracts)
.map(contractList => !!contractList)
.filter(loaded => loaded)
.take(1);
}
canActivate(): Observable<boolean> { return this.waitForData(); }
}
Run Code Online (Sandbox Code Playgroud)
路由:
const routes: Routes = [
{ path: 'app-list', canActivate: [ContractsLoadedGuard], component: AppListComponent },
];
Run Code Online (Sandbox Code Playgroud)
最后还有一个由@ngrx/router-store v4ROUTER_NAVIGATION动作触发的@ngrx/effects :
@Effect() routeChange$ = this.actions$
.ofType(ROUTER_NAVIGATION)
.filter((action: RouterNavigationAction) => action.payload.routerState.url.indexOf('/app-list') > -1)
.withLatestFrom(this.store.select(state => state.contracts))
.switchMap(([action, contracts]: ([RouterNavigationAction, ContractList])) =>
this.restClient.load(action.payload.routerState.queryParams, contract));
Run Code Online (Sandbox Code Playgroud)
不幸的是,当导航更改为/app-listngrx …
当我使用此效果注销时,我的oauth设置存在问题:
@Effect()
logout: Observable<Action> = this.actions.ofType(UserActions.LOGOUT)
.switchMap(() => Observable.of(this.afAuth.auth.signOut()))
.map(() => new UserActions.GetUser())
.catch(err => Observable.of(new UserActions.AuthError({error: err.message})));
Run Code Online (Sandbox Code Playgroud)
一切正常,UserActions.GetUser()正在被召唤.现在,如果我尝试使用此效果和此firebase auth函数登录:
@Effect()
googleLogin: Observable<Action> = this.actions.ofType(UserActions.GOOGLE_LOGIN)
.switchMap(() => Observable.fromPromise(this.loginWithGoogle()))
.map(() => new UserActions.GetUser())
.catch(err => Observable.of(new UserActions.AuthError({error: err.message})));
private loginWithGoogle() {
return this.afAuth.auth.signInWithPopup(new firebase.auth.GoogleAuthProvider());
}
Run Code Online (Sandbox Code Playgroud)
新的UserActions.GetUser()被调用,我可以在Redux DevTools中看到它,但实际的效果没有被调用,我在那里放了很多console.log,看看我是否在函数中做错了,但它没有被调用一切,我也有一个catch在GetUser,但是这也不能触发.
在这种情况下是否存在firebase的问题或者我是愚蠢的?
操作:
获得用户效果:
@Effect()
getUser: Observable<Action> = this.actions.ofType(UserActions.GET_USER)
.switchMap(() => {
console.log('test'); // <-- Not called
return this.afAuth.authState;
})
.map(()=> {
return new UserActions.Authenticated();
});
Run Code Online (Sandbox Code Playgroud)
** …
observable firebase-authentication ngrx ngrx-effects angular
我正在将Angular与NGRX效果一起使用,并且对可观察对象世界是陌生的。我想检查存储中是否存在数据,那么不应该调用API,而应该从存储中提取数据。我设法发现我可以使用withLatestFrom()来检查商店中的最新值。下一部分让我感到困惑,我无法正常工作。我当前的代码如下:
@Effect() getSomeContent$ = this.actions$
.ofType(GET_SOME_CONTENT)
.withLatestFrom(this.store$.select('store-section'))
.map(([action, store]) => {
const content = {};
if (store.someContent.length > 0) {
return new GetCategoryContentSuccessAction({ categoryContent: categories });
}
return Observable.from(action.payload);
})
.switchMap(payload => this.APIcall(payload)
.then(data => {
const content = {};
data.items.map((item) => {
const slug = data.slug;
content[slug] = {
info: datasomeData
};
});
return new GetSomeContentSuccessAction({ categoryContent: categories });
})
.catch((err) => {
return new GetFailureAction({ error: {} });
})
);
Run Code Online (Sandbox Code Playgroud)
我想使用某种if或else语句来检查商店。如果数据存在,我想将一个空对象发回给我必须处理的减速器。如果不是,我想调用API并将该数据发送回去。我不知道可观察对象是否可以分支,换句话说,可以做到吗?
有没有更好的方法可以实现这一目标?可能通过创建另一个操作来单独处理API。我想了解最佳实践的发展方向。任何帮助将不胜感激。
影响:
@Effect()
loadDocsEffect$ = this.actions$.pipe(
ofType(myActionTypes.LoadDocs),
mergeMap(action => this.myService.getDocs()),
map(data => new LoadDocsSuccess(data)),
catchError(error => Observable.of(new LoadDocsFailure(error)))
);
Run Code Online (Sandbox Code Playgroud)
当我返回数据时它可以工作,但是当服务器响应错误时(例如404),可观察对象已完成,并且在我第二次调度动作时不会触发效果。我寻找一种正确处理错误并继续观察到的流的方法,以便可以在我的组件中订阅它并采取相应的措施。
@ngrx Effect中的解决方案第二次不运行对我不起作用,或者我无法使其工作。
ngrx-effects ×10
angular ×8
ngrx ×7
observable ×3
ngrx-store ×2
rxjs ×2
angular10 ×1
jasmine ×1
javascript ×1
typescript ×1