热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

动作已正确调度,但减速器未调用注意

成功时,我调度一个Login操作和一个LoginSuccess操作。登录操作正确触发了reduc

成功时,我调度一个Login操作和一个Login Success操作。

登录操作正确触发了reducer。
成功操作具有有效负载时,它不会触发reducer(如果我删除有效负载,但没有用户,它将触发它)。

但是它确实可以正确触发导航效果,并且两个操作在redux开发工具中都是可见的。

成功登录后,我从firebase收到以下错误(即使我从诺言中恢复了用户):


  

core.js:6382错误TypeError:无法读取未定义的属性“ host”
      在Object.push ../ node_modules/@firebase/firestore/dist/index.cjs.js.Firestore.configureclient(http://localhost:4200/vendor.js:120980:33)
      在Object.push ../ node_modules/@firebase/firestore/dist/index.cjs.js.Firestore.ensureclientConfigured(http://localhost:4200/vendor.js:120972:18)
      在Object.get [as _isTerminated](http://localhost:4200/vendor.js:120926:18)
      在http://localhost:4200/vendor.js:128600:37
      在Array.forEach()
      处于冻结状态(http://localhost:4200/vendor.js:128590:40)
      在http://localhost:4200/vendor.js:128603:17
      在Array.forEach()
      处于冻结状态(http://localhost:4200/vendor.js:128590:40)
      在http://localhost:4200/vendor.js:128603:17

动作:

import { createaction,props } from '@ngrx/store';
import { User } from 'firebase';
export const login = createaction('[Authentication/API] Login');
export const loginSuccess = createaction(
'[Authentication/API] Login Success',props<{ user: User }>()
);
export const loginFail = createaction('[Authentication/API] Login Fail');

效果:

import { Injectable } from '@angular/core';
import { actions,createEffect,ofType } from '@ngrx/effects';
import { map,switchMap,tap,catchError } from 'rxjs/operators';
import { navigate } from 'src/app/store/router';
import * as Authenticationactions from './authentication.actions';
import { AuthenticationService } from '../services/authentication.service';
import { from,of } from 'rxjs';
@Injectable()
export class AuthenticationEffects {
constructor(
private actions$: actions,private authenticationService: AuthenticationService
) {}
login$ = createEffect(() =>
this.actions$.pipe(
ofType(Authenticationactions.login),switchMap(() =>
from(this.authenticationService.login()).pipe(
map(({ user }) => Authenticationactions.loginSuccess({ user })),catchError(() => of(Authenticationactions.loginFail()))
)
)
)
);
navigateToDefaultPageonSuccessfulLogin$ = createEffect(() =>
this.actions$.pipe(
ofType(Authenticationactions.loginSuccess),map(() => navigate({ url: 'transactions/import' }))
)
);
}

减速器:

import { action,createReducer,on } from '@ngrx/store';
import * as Authenticationactions from './authentication.actions';
import { User } from 'firebase';
export interface AuthenticationState {
user: User | null;
isLoading: boolean;
}
export const initialState: AuthenticatiOnState= {
user: null,isLoading: false
};
export const authenticatiOnReducer= createReducer(
initialState,on(Authenticationactions.login,state => ({ ...state,isLoading: true })),on(Authenticationactions.loginSuccess,(state,{ user }) => ({
...state,isLoading: false,user
})),on(Authenticationactions.loginFail,state => ({
...state,isLoading: false
}))
);
export function reducer(
state: AuthenticationState | undefined,action: action
) {
return authenticationReducer(state,action);
}

服务:

import { Injectable } from '@angular/core';
import { AngularFireAuth } from '@angular/fire/auth';
import { auth } from 'firebase/app';
@Injectable({
providedIn: 'root'
})
export class AuthenticationService {
constructor(private afAuth: AngularFireAuth) {}
login() {
return this.afAuth.auth.signInWithPopup(new auth.GoogleAuthProvider());
}
}


您应将Promise返回的signInWithPopup转换为Observable

login(): Observable {
const provider = new firebase.auth.GoogleAuthProvider();
return from(this.afAuth.auth.signInWithPopup(provider));
}

我还建议您使用其他方法登录并检索当前已签名的用户:

@Injectable()
export class AuthEffects {
check$ = createEffect(() => this.actions$.pipe(
ofType(authActions.check),switchMap(() => this.afAuth.authState.pipe(
map(user => user
? authActions.idAuthenticated({ user: user })
: authActions.idNotAuthenticated()
)
))
))
login$ = createEffect(() => this.actions$.pipe(
ofType(authActions.login),switchMap(() => this.authService.login().pipe(
map(() => authActions.check()),catchError(error => of(authActions.authError({ message: 'Login failed' })))
))
))

auth.service.ts:

login(): Observable {
const provider = new firebase.auth.GoogleAuthProvider();
return from(this.afAuth.auth.signInWithPopup(provider));
}
}

使用这种体系结构,您可以在初始化应用时调度check操作。如果用户已经登录,则将检索其凭据。

ngOnInit() {
this.store.dispatch(authActions.check());
}

如果用户尚未登录,则可以导航到错误页面。

注意

请注意您的navigateToDefaultPageOnSuccessfulLogin$效果,您正在调用不正确的方法来导航到url。

navigateToDefaultPageOnSuccessfulLogin$ = createEffect(() =>
this.actions$.pipe(
ofType(AuthenticationActions.loginSuccess),map(() => this.router.navigate(['transactions/import' }))
)
);
constructor(private router: Router,...) {}

推荐阅读
  • Servlet多用户登录时HttpSession会话信息覆盖问题的解决方案
    本文讨论了在Servlet多用户登录时可能出现的HttpSession会话信息覆盖问题,并提供了解决方案。通过分析JSESSIONID的作用机制和编码方式,我们可以得出每个HttpSession对象都是通过客户端发送的唯一JSESSIONID来识别的,因此无需担心会话信息被覆盖的问题。需要注意的是,本文讨论的是多个客户端级别上的多用户登录,而非同一个浏览器级别上的多用户登录。 ... [详细]
  • Gitlab接入公司内部单点登录的安装和配置教程
    本文介绍了如何将公司内部的Gitlab系统接入单点登录服务,并提供了安装和配置的详细教程。通过使用oauth2协议,将原有的各子系统的独立登录统一迁移至单点登录。文章包括Gitlab的安装环境、版本号、编辑配置文件的步骤,并解决了在迁移过程中可能遇到的问题。 ... [详细]
  • vue使用
    关键词: ... [详细]
  • IhaveconfiguredanactionforaremotenotificationwhenitarrivestomyiOsapp.Iwanttwodiff ... [详细]
  • 本文介绍了Web学习历程记录中关于Tomcat的基本概念和配置。首先解释了Web静态Web资源和动态Web资源的概念,以及C/S架构和B/S架构的区别。然后介绍了常见的Web服务器,包括Weblogic、WebSphere和Tomcat。接着详细讲解了Tomcat的虚拟主机、web应用和虚拟路径映射的概念和配置过程。最后简要介绍了http协议的作用。本文内容详实,适合初学者了解Tomcat的基础知识。 ... [详细]
  • WebSocket与Socket.io的理解
    WebSocketprotocol是HTML5一种新的协议。它的最大特点就是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送 ... [详细]
  • 本文介绍了一个适用于PHP应用快速接入TRX和TRC20数字资产的开发包,该开发包支持使用自有Tron区块链节点的应用场景,也支持基于Tron官方公共API服务的轻量级部署场景。提供的功能包括生成地址、验证地址、查询余额、交易转账、查询最新区块和查询交易信息等。详细信息可参考tron-php的Github地址:https://github.com/Fenguoz/tron-php。 ... [详细]
  • VueCLI多页分目录打包的步骤记录
    本文介绍了使用VueCLI进行多页分目录打包的步骤,包括页面目录结构、安装依赖、获取Vue CLI需要的多页对象等内容。同时还提供了自定义不同模块页面标题的方法。 ... [详细]
  • 微信官方授权及获取OpenId的方法,服务器通过SpringBoot实现
    主要步骤:前端获取到code(wx.login),传入服务器服务器通过参数AppID和AppSecret访问官方接口,获取到OpenId ... [详细]
  • Jboss的EJB部署描述符standardjaws.xml配置步骤详解
    本文详细介绍了Jboss的EJB部署描述符standardjaws.xml的配置步骤,包括映射CMP实体EJB、数据源连接池的获取以及数据库配置等内容。 ... [详细]
  • 电话号码的字母组合解题思路和代码示例
    本文介绍了力扣题目《电话号码的字母组合》的解题思路和代码示例。通过使用哈希表和递归求解的方法,可以将给定的电话号码转换为对应的字母组合。详细的解题思路和代码示例可以帮助读者更好地理解和实现该题目。 ... [详细]
  • 基于layUI的图片上传前预览功能的2种实现方式
    本文介绍了基于layUI的图片上传前预览功能的两种实现方式:一种是使用blob+FileReader,另一种是使用layUI自带的参数。通过选择文件后点击文件名,在页面中间弹窗内预览图片。其中,layUI自带的参数实现了图片预览功能。该功能依赖于layUI的上传模块,并使用了blob和FileReader来读取本地文件并获取图像的base64编码。点击文件名时会执行See()函数。摘要长度为169字。 ... [详细]
  • 本文介绍了UVALive6575题目Odd and Even Zeroes的解法,使用了数位dp和找规律的方法。阶乘的定义和性质被介绍,并给出了一些例子。其中,部分阶乘的尾零个数为奇数,部分为偶数。 ... [详细]
  • 本文介绍了一道经典的状态压缩题目——关灯问题2,并提供了解决该问题的算法思路。通过使用二进制表示灯的状态,并枚举所有可能的状态,可以求解出最少按按钮的次数,从而将所有灯关掉。本文还对状压和位运算进行了解释,并指出了该方法的适用性和局限性。 ... [详细]
  • linux进阶50——无锁CAS
    1.概念比较并交换(compareandswap,CAS),是原⼦操作的⼀种,可⽤于在多线程编程中实现不被打断的数据交换操作࿰ ... [详细]
author-avatar
李-诗-妍_519
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有