मेरे पास एक कोणीय 7 ऐप है जिसमें मेरे पास एक पोस्ट कॉल है और उस पोस्ट कॉल प्रतिक्रिया के आधार पर मैं गार्ड को सक्रिय/निष्क्रिय बनाना चाहता हूं। मेरे पास मेरा रूट गार्ड इस तरह है

canActivate = (_router: ActivatedRouteSnapshot): boolean => {
    console.log('in link expiry guard')
    let userEmail = _router.paramMap.get('email');
    let isAllow;

    console.log('params : ', userEmail)
    userEmail = this._utilityService.decryptMsgByCryptoJs(userEmail);
    console.log('user email : ', userEmail)
    this._dataService.post(this._const.userResetPasswordLinkExpiry, { email: userEmail }).subscribe(resp => {
        console.log('verify response : ',resp)
        if (resp.success) {
            console.log('in success')
            isAllow = true;
        } else {
            isAllow = false;
        }
    })
    console.log('allow flag  : ',isAllow)
    if (isAllow) {
        console.log('in allow')
        return true;
    } else {
        console.log('in not allow')
        this._utilityService.navigate('/login');
        this._dataService.exhangeResetPasswordObsMsg({ event: 'linkExpired' });
        return false;
    }
}

लेकिन समस्या यह है कि जब मेरी http post कॉल चल रही है, तो मेरा गार्ड पूरी तरह से निष्पादित करता है और झूठी वापसी करता है और उसके बाद पोस्ट कॉल से प्रतिक्रिया आ रही है। मैं इस परिदृश्य को कैसे प्रबंधित कर सकता हूं ताकि मैं http post कॉल प्रतिक्रिया के आधार पर मार्ग को सही या गलत बना सकूं।

-1
Fahad Hassan 25 फरवरी 2020, 23:15
समस्या यह है कि आप समवर्ती फ़ंक्शन के बाहर लौट रहे हैं और कोड मूल्यांकन करता रहता है। बाहर की बजाय पोस्ट कॉल के अंदर लौटें और बूलियन के बजाय Promise या Observable लौटाएं। CanActivate इनमें से किसी एक को लौटा सकता है -> angular.io/api/router/CanActivate
 – 
sinanspd
25 फरवरी 2020, 23:18
क्या आप मुझे उत्तर में बता सकते हैं?
 – 
Fahad Hassan
25 फरवरी 2020, 23:22
मेरा अद्यतन प्रश्न देखें मैंने अपना रूट गार्ड अपडेट कर दिया है। लेकिन अब यह लाइन canActivate = (_router: ActivatedRouteSnapshot): Observable<boolean> पर एक त्रुटि दे रहा है। यह कहना कि function must return a value
 – 
Fahad Hassan
25 फरवरी 2020, 23:24
हाय, आप गुरद के अंदर http के बजाय रूट रिओल्सवर का उपयोग कर सकते हैं।
 – 
Rahul Rathore
25 फरवरी 2020, 23:26
आपको अभी भी अपनी पूरी कॉल वापस करने की आवश्यकता है, देखें: stackoverflow.com/questions/37948068/…\
 – 
sinanspd
25 फरवरी 2020, 23:27

1 उत्तर

यदि आप अपने canActivate फ़ंक्शन के अंदर एक Http अनुरोध करना चाहते हैं, तो आपको boolean के बजाय एक Observable<boolean> वापस करना होगा, क्योंकि अब आप एक एसिंक्रोनस क्रिया कर रहे हैं।

और चूंकि आप फेल होने पर नेविगेट करना चाहते हैं, आपको इसके बजाय Observable<boolean | UrlTree> वापस लौटना चाहिए।

सरल संस्करण

constructor(private router: Router) { }

canActivate(route: ActivatedRouteSnapshot, 
    state: RouterStateSnapshot): Observable<boolean | UrlTree> {
  return this.http.post(url, body).pipe(
    map((resp: any) => resp.success ? true : this.router.parseUrl('/path'))
  );   
}

हम देखने योग्य http अनुरोध वापस कर रहे हैं (राउटर इसे सब्सक्राइब करके आमंत्रित करेगा), और प्रतिक्रिया को या तो मैप कर रहा है

  • true - राउटर सुरक्षित मार्ग पर जा सकता है
  • UrlTree - राउटर को हमारे द्वारा वापस किए गए मार्ग पर नेविगेट करना चाहिए

आपके उदाहरण पर लागू

यदि हम इसे आपके उदाहरण पर लागू करते हैं, तो हमें पाइप में थोड़ा और काम करने की आवश्यकता है, क्योंकि आपके पास एक अतिरिक्त सेवा कॉल है।

// TODO: inject other services
constructor(private router: Router) { }

canActivate(route: ActivatedRouteSnapshot, 
      state: RouterStateSnapshot): Observable<boolean | UrlTree> {
    const userEmail = route.paramMap.get('email');

    // I am assuming this is a synchronous call
    userEmail = this._utilityService.decryptMsgByCryptoJs(userEmail);

    const url = this._const.userResetPasswordLinkExpiry;
    const body = { email: userEmail };

    return this._dataService.post(url, body).pipe(
      // initial map from response to true/false
      map((resp: any) => resp.success),

      // perform an action if false
      tap(success => {
        if (!success) {
          // I'm assuming this is synchronous. If not, you will need to do a switchMap
          this._dataService.exhangeResetPasswordObsMsg({ event: 'linkExpired' });
        }
      }),
      // final map to boolean | UrlTree
      map(success => success ? true : this.router.parseUrl('/login'))
    );   
}

वहाँ कुछ सेवा कॉल हैं जो मुझे लगता है कि समकालिक हैं। यह उत्तर दर्शाता है कि आप canActivate के अंदर एक एसिंक्रोनस कॉल कैसे करते हैं और या तो राउटर को नेविगेट करने की अनुमति देते हैं या नेविगेट करने के लिए एक वैकल्पिक मार्ग वापस करते हैं।

0
Kurt Hamilton 26 फरवरी 2020, 01:27
अब यह इस तरह की त्रुटि दे रहा है Cannot find name 'UrlTree'.
 – 
Fahad Hassan
25 फरवरी 2020, 23:41
मैंने आयात का सारा वहां नहीं डाला। यदि आप वीएस कोड का उपयोग कर रहे हैं तो आपको इसे स्वचालित रूप से आयात करने में सक्षम होना चाहिए। यदि नहीं, तो आप इसे '@ कोणीय/राउटर' से मैन्युअल रूप से आयात कर सकते हैं
 – 
Kurt Hamilton
25 फरवरी 2020, 23:43
मैंने सभी आयातों के साथ किया है लेकिन उसके बाद यह हो रहा है। कृपया इसे देखें ibb.co/tB3htqy
 – 
Fahad Hassan
25 फरवरी 2020, 23:45
त्रुटि canActivate पर है। आप अभी भी canActivate = () लिखकर इसे एक फ़ंक्शन असाइन करने का प्रयास कर रहे हैं। आपको बस इसे मेरे उत्तर की तरह सामान्य वर्ग फ़ंक्शन canActivate(/. params ./) के रूप में लिखने की आवश्यकता है।
 – 
Kurt Hamilton
25 फरवरी 2020, 23:47
मेरा अद्यतन प्रश्न देखें। मैंने आपके उत्तर के अनुसार अपनी गार्ड परिभाषा को अपडेट कर दिया है लेकिन फिर भी वही त्रुटि हो रही है।
 – 
Fahad Hassan
25 फरवरी 2020, 23:52