2017-12-01 2 views
0

Wenn jemand von euch das sehe, habe ich eine Frage, ich bin neu bei redux und komme aus der eckigen und Dienstleistungslogik, also weiß ich irgendwie, wie redux funktioniert. Ich benutze nur zwei epische Listener (einen, um GET-Methode aus dem Dienst und einen für POST aufzurufen) + Dienste (zum Abrufen von Daten aus einer API). Also, wann immer ich api anrufen muss, mache ich ein Objekt mit einer API-Konfiguration einschließlich URL, Param und wenn Autorisierungsheader in der API enthalten ist jetzt die Sache, ist diese Sache gut, wenn ich eine Aktion zu einer Zeit senden, aber wenn ich habe mehrere Aktionen zu machen bedeutet, dass mehrere get oder posts im epic stehen bleiben, nachdem der Dienst und die epische Arbeit erledigt wurden und nicht zum Reducer gehen, um die Daten zu speichern, und gibt mir einen Fehler. Actions must be plain objects. Use custom middleware for async actions Ich weiß, dass bei meiner Implementierung etwas nicht stimmt. Es wäre großartig, wenn es auf diese Weise funktioniert, sonst muss ich zu anderen Diensten wie Thunk oder etwas anderem wechseln.Daten gehen nicht von episch zu Reduzierer

` 
GetEpic = (action$) => 
      action$.ofType(Action.Get) 
       .switchMap(({ payload }) => { 
        let { api, param, reqHeader, waitFor } = payload; 
        delete payload.api; 
        delete payload.param; 
        delete payload.reqHeader; 
        return HttpService.post(api, param, reqHeader, payload).then((userInfo) => { 
         if (userInfo.status && userInfo.status != 200) { 
          return { 
           type: 'ERROR' 
          } 
         } 
         return this.translateDataAndReturnType(userInfo, api, 'get', waitFor); 
        }).catch(() => { 
         return { 
          type: 'ERROR' 
         } 
        }) 
       }) 

translateDataAndReturnType(data, api, method, waitFor) { 
     if (data && api) { 
      this.count += 1; 
      let actionInfo = this.routesData.find((d, i) => { 
       return d.route == api 
      }) 
      let routeAction = Object.assign({}, actionInfo); 
      routeAction.payload = data; 
      this.localDate[routeAction.route] = data; 
      delete routeAction.route; 
      if (typeof waitFor == 'number') { 
       this.waitFor = waitFor; 
       this.count = 0; 
       this.count += 1; 
      } 
      if (this.count == this.waitFor) { 
       routeAction.payload = this.localDate; 
       if (this.actions) { 
        routeAction.type = this.actions; 
       } 
       return routeAction; 
      } 
     } 
    } 
` 

mit Antwort aktualisiert
Was falsch zu machen war ich versuche, Antwort mehrere Aktion Schuss von meiner Komponente an zu erhalten, sobald die jedoch nicht möglich, so änderte ich meine Strategie für einzelne Aktion mit mehreren APIs zu verwenden dass ich eine json mit einer Route erstellt und apis

`this.routeConfig = { 
    "countriesCitesTimezone": [ 
       { route: 'countries', type: 'SUCCESS-COUNTRIES', param: '', reqHeader: false }, 
       { route: 'cities', param: '', reqHeader: false }, 
       { route: 'timezone', param: '', reqHeader: false } 
      ] 
}` 

so, wenn ich rufe müssen eine Aktion i die Aktion mit einigen Konfiguration nennt wie

, die dann durch epische

behandelt wird
`GetEpic = (action$) => 
      action$.ofType(Action.Get) 
       .switchMap(({ payload }) => { 
        let requests = this.routesConfig[payload.route]; 
        return Observable.forkJoin(
        requests.map((d, ind) => { 
         let param = d.param; 
         if (payload.params.length > 0) { 
          param = payload.params[ind]; 
         } 
         return (HttpService.get(d.route, param, d.reqHeader)); 
        }) 
       ).map((x) => { 
        console.log(x); 
        let result = {}; 
        requests.map((d, ind) => { 
         result[d.route] = x[ind] 
        }) 
        return ({ 
         type: requests[0].type, 
         payload: result 
        }) 
       }) 
       })` 
+0

Bitte Code angeben. –

+0

hinzugefügt Code jetzt die Sache ist, wenn ich die 'Action.Get' mehrere Male mit einer anderen Konfiguration für' HttpService' aufrufen, dann bekomme ich den Fehler, der besagt, dass Aktionen einfach sein müssen ... ' –

Antwort

0

Ich denke, was Sie suchen mergeMap ist statt switchMap.

switchMap WILL:

Projiziert jeden Quellwert auf einen beobachtbaren, die in der Ausgabe Observable zusammengeführt wird, Werte Emittieren nur aus dem zuletzt Observable projizierte.

Also, wenn switchMap() verwendet, jede neue Aktion vom Typ Action.Get wird die Emission von früherem Service-Aufruf Reaktion verhindern, wenn es noch anhängig ist.

Auch Ihr Service-Aufruf unter der Annahme gibt ein Promise, sollten Sie den HttpService.post() Anruf in Observable.fromPromise() Einwickeln in Betracht ziehen. Ich glaube der Grund, warum Sie den Actions must be plain objects... Fehler bekommen, ist, weil Sie eine Promise ausstrahlen, die dann in den Laden versandt wird.

Verwandte Themen