How to make an API call in Angular 2? - http

There are lots of resources out there already but I haven't been able to find one that works for one reason or another. Take a generic example: I want to get the response from http://swapi.co/api/people, which will be a list of people from Star Wars.
import {Injectable } from '#angular/core';
import {Http, Response} from '#angular/http';
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/operator/map';
#Injectable()
export class OombaDataService {
constructor(private http: Http) {}
private usersUrl = 'http://swapi.co/api/people/';
getData() {
return this.http.get(this.usersUrl)
.map(this.extractData)
}
private extractData(res: Response) {
let body = res.json();
return body.data || { };
}
private handleError (error: any) {
// In a real world app, we might use a remote logging infrastructure
// We'd also dig deeper into the error to get a better message
let errMsg = (error.message) ? error.message :
error.status ? `${error.status} - ${error.statusText}` : 'Server error';
console.error(errMsg); // log to console instead
return Observable.throw(errMsg);
}
}
A lot of this should be correct since it's based on Angular's own tutorial on the matter. But for whatever reason, when I call it in my components, it just returns an observable object without the JSON data. What am I missing?

At this method:
private extractData(res: Response) {
let body = res.json();
return body.data || { };
}
At the first line, you parse the result of the API call as JSON into a JavaScript object.
Then you return the property data of that object, if it exists. If it doesn't exist, you return an empty object ({ }).
The thing is that the API at http://swapi.co/api/people/ does not bring a response that contains a data property, which means that the extractData() method is always returning an observable of an empty object ({ }).
Besides that, the getData() really returns an Observable, so to get its value, you must subscribe to it, such as:
#Component({
...
providers: [OombaDataService]
})
export class SomeComponent {
constructor(oombaDataService: OombaDataService) {
oombaDataService.getData().subscribe(
x => {
console.log("VALUE RECEIVED: ",x);
},
x => {
console.log("ERROR: ",x);
},
() => {
console.log("Completed");
}
);
}
}
And, since, as said, that API's response does not have any .data property in it, the extractData() should really be (at least until you figure out what you want):
private extractData(res: Response) {
return res.json();
}
That should get things working. Here's a working plunker.

Related

Angular2 ( 2.2.1 ) Http post request progress bar [duplicate]

Is there currently a way within Angular 2 to retrieve the progress (i.e. percentage done) of an ajax call, using the angular2/http module?
I use the following code to make my HTTP calls:
let body = JSON.stringify(params);
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
this.http.post(url, body, options)
.timeout(10000, new Error('Timeout exceeded during login'))
.toPromise()
.then((res) => {
...
}).catch((err) => {
...
});
The goal is to write a synchronisation system. The post will return a lot of data, and I want to give the user an indication on how long the syncing will take.
Currently (from v. 4.3.0, when using new HttpClient from #ngular/common/http) Angular provides listening to progress out of the box. You just need to create HTTPRequest object as below:
import { HttpRequest } from '#angular/common/http';
...
const req = new HttpRequest('POST', '/upload/file', file, {
reportProgress: true,
});
And when you subscribe to to request you will get subscription called on every progress event:
http.request(req).subscribe(event => {
// Via this API, you get access to the raw event stream.
// Look for upload progress events.
if (event.type === HttpEventType.UploadProgress) {
// This is an upload progress event. Compute and show the % done:
const percentDone = Math.round(100 * event.loaded / event.total);
console.log(`File is ${percentDone}% uploaded.`);
} else if (event instanceof HttpResponse) {
console.log('File is completely uploaded!');
}
});
More info here.
You could leverage the onprogress event provided by XHR (see this plunkr: http://plnkr.co/edit/8MDO2GsCGiOJd2y2XbQk?p=preview).
This allows to get hints about the progress of the download. This isn't supported out of the box by Angular2 but you can plug it by extended the BrowserXhr class:
#Injectable()
export class CustomBrowserXhr extends BrowserXhr {
constructor(private service:ProgressService) {}
build(): any {
let xhr = super.build();
xhr.onprogress = (event) => {
service.progressEventObservable.next(event);
};
return <any>(xhr);
}
}
and override the BrowserXhr provider with the extended:
bootstrap(AppComponent, [
HTTP_PROVIDERS,
provide(BrowserXhr, { useClass: CustomBrowserXhr })
]);
See this question for more details:
Angular2 / RxJS - updating variable after getting data from Http observable
When you make http cals in angular2, it returns an Observable of type Response, this response is created inside class called XHRConnection where all the magic happens.
The XHRConnection builds the response by listening to XMLHttpRequest's load event, this means it will return one response at the end of the request.
Now to be able to alter this behavior we need to make our connection class listen to the progress event.
So we need to create custom Connection class, to handle the response as we see fit.
I did it this way,
Take note that my php API returns multi response in a single request and this responses are plain strings.
my_backend.ts
import {Injectable} from "angular2/core";
import {Observable} from "rxjs/Observable";
import {Observer} from "rxjs/Observer";
import {Connection,ConnectionBackend} from "angular2/src/http/interfaces";
import {ReadyState, RequestMethod, ResponseType} from "angular2/src/http/enums";
import {ResponseOptions} from "angular2/src/http/base_response_options";
import {Request} from "angular2/src/http/static_request";
import {Response} from "angular2/src/http/static_response";
import {BrowserXhr} from "angular2/src/http/backends/browser_xhr";
import {Headers} from 'angular2/src/http/headers';
import {isPresent} from 'angular2/src/facade/lang';
import {getResponseURL, isSuccess} from "angular2/src/http/http_utils"
export class MyConnection implements Connection {
readyState: ReadyState;
request: Request;
response: Observable<Response>;
constructor(req: Request, browserXHR: BrowserXhr, baseResponseOptions?: ResponseOptions) {
this.request = req;
this.response = new Observable<Response>((responseObserver: Observer<Response>) => {
let _xhr: XMLHttpRequest = browserXHR.build();
_xhr.open(RequestMethod[req.method].toUpperCase(), req.url);
// save the responses in array
var buffer :string[] = [];
// load event handler
let onLoad = () => {
let body = isPresent(_xhr.response) ? _xhr.response : _xhr.responseText;
//_xhr.respons 1 = "Loading data!"
//_xhr.respons 2 = "Loading data!Ready To Receive Orders."
// we need to fix this proble
// check if the current response text contains the previous then subtract
// NOTE: I think there is better approach to solve this problem.
buffer.push(body);
if(buffer.length>1){
body = buffer[buffer.length-1].replace(buffer[buffer.length-2],'');
}
let headers = Headers.fromResponseHeaderString(_xhr.getAllResponseHeaders());
let url = getResponseURL(_xhr);
let status: number = _xhr.status === 1223 ? 204 : _xhr.status;
let state:number = _xhr.readyState;
if (status === 0) {
status = body ? 200 : 0;
}
var responseOptions = new ResponseOptions({ body, status, headers, url });
if (isPresent(baseResponseOptions)) {
responseOptions = baseResponseOptions.merge(responseOptions);
}
let response = new Response(responseOptions);
//check for the state if not 4 then don't complete the observer
if(state !== 4){
//this will return stream of responses
responseObserver.next(response);
return;
}
else{
responseObserver.complete();
return;
}
responseObserver.error(response);
};
// error event handler
let onError = (err: any) => {
var responseOptions = new ResponseOptions({ body: err, type: ResponseType.Error });
if (isPresent(baseResponseOptions)) {
responseOptions = baseResponseOptions.merge(responseOptions);
}
responseObserver.error(new Response(responseOptions));
};
if (isPresent(req.headers)) {
req.headers.forEach((values, name) => _xhr.setRequestHeader(name, values.join(',')));
}
_xhr.addEventListener('progress', onLoad);
_xhr.addEventListener('load', onLoad);
_xhr.addEventListener('error', onError);
_xhr.send(this.request.text());
return () => {
_xhr.removeEventListener('progress', onLoad);
_xhr.removeEventListener('load', onLoad);
_xhr.removeEventListener('error', onError);
_xhr.abort();
};
});
}
}
#Injectable()
export class MyBackend implements ConnectionBackend {
constructor(private _browserXHR: BrowserXhr, private _baseResponseOptions: ResponseOptions) {}
createConnection(request: Request):MyConnection {
return new MyConnection(request, this._browserXHR, this._baseResponseOptions);
}
}
And in the app.component.ts
import {Component, provide} from 'angular2/core';
import {HTTP_PROVIDERS,XHRBackend} from 'angular2/http';
import {MyBackend} from './my_backend';
#Component({
selector: 'my-app',
providers: [
HTTP_PROVIDERS,
MyBackend,
provide(XHRBackend, {useExisting:MyBackend})
]
.
.
.
Now calling http.get will return a steam of responses.
#Bartek Chichoki's answer is correct but it was not working for my case.
Adding observe: 'events' did the trick for me
const req = new HttpRequest('POST', '/upload/file', file, {
reportProgress: true,
observe: 'events'
});
Hope it helps
I strongly recomend using this
https://www.npmjs.com/package/angular-progress-http
otherwise messing around with xhr will make you miss sessions cookies and other stuffs
besides it'll be more portable and way easier to implement

Angular2 not sending HTTP GET

The code listed in (A) never sends its HTTP request when test() is called whereas the almost identical code in (B) does work. Any idea what the problem is? I know whether the request is sent by watching the server logs. Also, if I make the request in (A) manually by pasting it into the browser, I get the expected response. I'm stumped!
(A)
import { Constants } from '../toplevel/constants'
import { Injectable } from '#angular/core';
import { Http, Response, Headers, RequestOptions } from '#angular/http';
import { Observable} from 'rxjs/Rx';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
#Injectable()
export class SigninService {
constructor (private http: Http, private constants : Constants) {
}
getToken(username: string, password: string) : Observable<string>{
var url = `${this.constants.apiRoot}/users/${username}?${password}`
console.log(`Calling api server with url ${url}`)
return this.http.get(url)
.map((res:Response) => JSON.stringify(res.json()))
.catch((error:any) => Observable.throw(error.json().error || 'Server error'));
}
test() {
this.getToken('jc', 'yadayada')
}
}
(B: excerpt)
getDocument(id: string) : Observable<Document>{
return this.http.get(`${this.apiUrl}/documents/${id}`)
.map((res:Response) => new Document(res.json()['document']))
.catch((error:any) => Observable.throw(error.json().error || 'Server error'));
}
Your sequence is cold. You need to change your test to:
this.getToken('jc', 'yadayada').subscribe()
to make it active and send the request

Asynchronicity issue with an Angular 2 app and the Angular 2 router

I am facing a tricky issue with asynchronicity in an angular 2 app.
I am basically trying to rehydrate/reload information from the backend when the app is reloaded/bootstrapped in the user's browser (think F5/refresh). The issue is that before the backend async method returns the result, a router guard is called and blocks...
I reload the information from the root component's ngOnInit method as follows:
from root component:
ngOnInit() {
//reloadPersonalInfo returns an Observable
this.sessionService.reloadPersonalInfo()
.subscribe();
}
from sessionService:
reloadPersonalInfo() {
//FIRST: the app execution flow gets here
let someCondition: boolean = JSON.parse(localStorage.getItem('someCondition'));
if (someCondition) {
return this.userAccountService.retrieveCurrentUserAccount()
.switchMap(currentUserAccount => {
//THIRD: and finally, the execution flow will get there and set the authenticated state to true (unfortunately too late)...
this.store.dispatch({type: SET_AUTHENTICATED});
this.store.dispatch({type: SET_CURRENT_USER_ACCOUNT, payload: currentUserAccount});
return Observable.of('');
});
}
return Observable.empty();
}
The trouble is that I have a router CanActivate guard as follows:
canActivate() {
//SECOND: then the execution flow get here and because reloadPersonalInfo has not completed yet, isAuthenticated will return false and the guard will block and redirect to '/signin'
const isAuthenticated = this.sessionService.isAuthenticated();
if (!isAuthenticated) {
this.router.navigate(['/signin']);
}
return isAuthenticated;
}
isAuthenticated method from sessionService:
isAuthenticated(): boolean {
let isAuthenticated = false;
this.store.select(s => s.authenticated)
.subscribe(authenticated => isAuthenticated = authenticated);
return isAuthenticated;
}
So to recap:
FIRST: the reloadPersonalInfo method on sessionService is called by root component ngOnInit. The execution flow enters this method.
SECOND: in the meantime, the router guard is called and sees that the state of authenticated is false (because reloadPersonalInfo has not completed yet and therefore not set the authenticated state to true.
THIRD: reloadPersonalInfo completes too late and sets the authenticated state to true (but the router guard has already blocked).
Can anyone please help?
edit 1: Let me stress that the authenticated state that matters is the one in the store; it is set by this line: this.store.dispatch({type: SET_AUTHENTICATED});.
edit 2: I changed the condition from authenticated to someCondition in order to reduce confusion. Previously, there was another state variable called authenticated...
edit 3: I have changed the isAuthenticated() method return type to Observable<boolean> instead of boolean (to follow Martin's advice) and adapted the canActivate method as follows:
canActivate() {
return this.sessionService.isAuthenticated().map(isAuthenticated => {
if (isAuthenticated) {
return true;
}
this.router.navigate(['/signin']);
return false;
});
}
from sessionService:
isAuthenticated(): Observable<boolean> {
return this.store.select(s => s.authenticated);
}
It makes no difference unfortunately...
Can someone please advise as to how to sort this asynchronicity issue?
There should be two possible ways to solve this:
Solution 1
The quickest, would be to distinguish your isAuthenticated not into 2 but 3 states, this way you can encode one more cruical piece of information into the state: At the time of bootstrapping(when no response from the server has been received), there is no way the client can know for sure if its credentials/tokens are valid or not, thus the state should correctly be "unknown".
First you have to change the initial state of authenticated in your store to null (you also may choose undefined or even use numbers depending on your personal taste). And then you just have to add a .filter to your guard, that renders the guard practically "motionless":
canActivate() {
return this.sessionService.isAuthenticated()
.filter(isAuthenticated => isAuthenticated !== null) // this will cause the guard to halt until the isAuthenticated-question/request has been resolved
.do(isAuth => (if (!isAuth) {this.router.navigate(['/signin'])}));
}
Solution 2
The second solution would be very similar, but instead of encoding a 3rd state into authenticated you'd add a new flag to your store called authRequestRunning, that is set to true while the auth-request is being made, and set to false after it completes. Your guard would then look only slightly different:
canActivate() {
return this.sessionService.isAuthenticated()
.switchMap(isAuth => this.sessionService.isAuthRequestRunning()
.filter(running => !running) // don't emit any data, while the request is running
.mapTo(isAuth);
)
.do(isAuth => (if (!isAuth) {this.router.navigate(['/signin'])}));
}
With solution #2 you might have some more code. and you have to be careful that the authRequestRunning is set to false first before the authenticated-state is updated.
Edit: I have edited the code in solution #2, so the order of setting the running-status and the auth-status does not matter any more.
The reason why I would use solution #2 is, because in most cases such a state-flag already exists and is being used to display a loading-indicator or something like that.
canActivate itself can return an Observable.
Instead of returning the boolean result in canActivate, return the isAuthenticated Observable.
why are you not setting Authenticated before you give a retrieveCurrentUserAccount call? IT seems you already know if your user is authenticated or not based upon the value inside localStorage
if (isAuthenticated) {
// set before you give a async call.
this.store.dispatch({type: SET_AUTHENTICATED});
return this.userAccountService.retrieveCurrentUserAccount()
.switchMap(currentUserAccount => {
//THIRD: and finally, the execution flow will get there and set the authenticated state to true (unfortunately too late)...
this.store.dispatch({type: SET_CURRENT_USER_ACCOUNT, payload: currentUserAccount});
return Observable.of('');
});
}
Update
Try below,
import { Component, Injectable } from '#angular/core';
import { Router, Routes, RouterModule, CanActivate } from '#angular/router';
import { Subject } from 'rxjs/Subject';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/take';
#Injectable()
export class SessionService{
private _isAuthenticated: Subject<boolean> = new Subject<boolean>();
public get isAuthenticated(){
return this._isAuthenticated.asObservable();
}
reloadPersonalInfo(){
setTimeout(() => {
this._isAuthenticated.next(true);
// do something else too...
}, 2000);
}
}
#Component({
selector: 'my-app',
template: `<h3>Angular CanActivate observable</h3>
<hr />
<router-outlet></router-outlet>
`
})
export class AppComponent {
constructor(private router: Router,
private sessionService : SessionService) { }
ngOnInit() {
this.sessionService.reloadPersonalInfo();
}
}
#Component({
template: '<h3>Dashboard</h3>'
})
export class DashboardComponent { }
#Component({
template: '<h3>Login</h3>'
})
export class LoginComponent { }
#Injectable()
export class DashboardAuthGuard implements CanActivate {
constructor(private router: Router, private sessionService : SessionService) { }
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot){
return this.sessionService.isAuthenticated.map(res => {
if(res){
return true;
}
this.router.navigate(['login']);
}).take(1);
}
}
let routes: Routes = [
{
path: '',
redirectTo: '/dashboard',
pathMatch: 'full'
},
{
path: 'dashboard',
canActivate: [DashboardAuthGuard],
component: DashboardComponent
},
{
path: 'login',
component: LoginComponent
}
]
export const APP_ROUTER_PROVIDERS = [
DashboardAuthGuard
];
export const routing: ModuleWithProviders
= RouterModule.forRoot(routes);
Here is the Plunker!!
Hope this helps!!

Angular2 http get request with Observables and dynamic url params. How to?

Having this angular2 service taken from official docs with Observable, trying to modify to can pass on fly to the base heroesUrl dynamic parameters like app/heroes/{{country}} and use it like
getHeroes(country) {}
import { Injectable } from '#angular/core';
import { Http, Response } from '#angular/http';
import { Hero } from './hero';
import { Observable } from 'rxjs/Observable';
#Injectable()
export class HeroService {
constructor (private http: Http) {}
private heroesUrl = 'app/heroes'; // URL to web API
getHeroes (): Observable<Hero[]> {
return this.http.get(this.heroesUrl)
.map(this.extractData)
.catch(this.handleError);
}
private extractData(res: Response) {
let body = res.json();
return body.data || { };
}
private handleError (error: any) {
// In a real world app, we might use a remote logging infrastructure
// We'd also dig deeper into the error to get a better message
let errMsg = (error.message) ? error.message :
error.status ? `${error.status} - ${error.statusText}` : 'Server error';
console.error(errMsg); // log to console instead
return Observable.throw(errMsg);
}
}
How would I do that?
I think you just need to do following things if I understood your point,
getHeroes(country) {}
export class HeroService {
constructor (private http: Http) {}
private heroesUrl = 'app/heroes'; // URL to web API
getHeroes (country): Observable<Hero[]> { //<-----added parameter
return this.http.get(this.heroesUrl + '/' + country) //<-----changed
.map(this.extractData)
.catch(this.handleError);
}
...
...
}

redux-promise with Axios, and how do deal with errors?

So, I see on an error, redux-promise hands me back error: true, along with the payload, but that is once it hits the reducer... to me, decoupling the request AND error condition is a bit odd, and seems inappropriate. What is an effective way to also deal with error condition when using axios w/ reduc-promise (middleware).. here is the gist of what i have..
in action/
const request = axios(SOME_URL);
return {
type: GET_ME_STUFF,
payload: request
}
in reducer/
const startState = {
whatever: [],
error: false
}
case GET_ME_STUFF:
return {...state, startState, {stuff:action.payload.data, error: action.error? true : false}}
etc... then I can deal with the error.. so, my api call is now split into two seperate areas and that seems wrong.... there must be something I am missing here. I would think in the /actions I can pass in a callback that handles a new action etc.. or something, but not split it.
I've had to go through a similar situation. The challenge is that you likely won't be able to evaluate the results of the promise until it is at the reducer. You could handle your exceptions there but it's not the best pattern. From what I've read reducers are meant only to return appropriate pieces of state based on action.type and do nothing else.
So, enter an additional middleware, redux-thunk. Instead of returning an object, it returns a function, and it can coexist with promise.
It's explained quite well at http://danmaz74.me/2015/08/19/from-flux-to-redux-async-actions-the-easy-way/ [archived here]. Essentially, you can evaluate the promise here and dispatch through the other action creators before the promise result hits the reducers.
In your actions file, add additional action creators that would handle the success and error (and any other) states.
function getStuffSuccess(response) {
return {
type: GET_ME_STUFF_SUCCESS,
payload: response
}
}
function getStuffError(err) {
return {
type: GET_ME_STUFF_ERROR,
payload: err
}
}
export function getStuff() {
return function(dispatch) {
axios.get(SOME_URL)
.then((response) => {
dispatch(getStuffSuccess(response))
})
.catch((err) => {
dispatch(getStuffError(err))
})
}
}
return null
This is roughly to how you might translate your pseudocode to what is explained at the link. This handles evaluating the promise directly in your action creator and firing off the appropriate actions and payloads to your reducers which follows the convention of action -> reducer -> state -> component update cycle. I'm still pretty new to React/Redux myself but I hope this helps.
The accepted answer doesn't make use of redux-promise. Since the question is actually about handling errors using redux-promise I provide another answer.
In the reducer you should inspect the existence of the error attribute on the action object:
// This is the reducer
export default function(previousState = null, action) {
if (action.error) {
action.type = 'HANDLE_XHR_ERROR'; // change the type
}
switch(action.type) {
...
And change the type of the action, triggering a state change for an error handling component that you have set up for this.
You can read a bit more about it here on github.
It looks like you can catch the error where you make the dispatch, then make an separate error dispatch if it happens. It's a bit of a hack but it works.
store.dispatch (function (dispatch) {
dispatch ({
type:'FOO',
payload:axios.get(url)
})
.catch (function(err) {
dispatch ({
type:"FOO" + "_REJECTED",
payload:err
});
});
});
and in the reducer
const reducer = (state=initialState, action) => {
switch (action.type) {
case "FOO_PENDING": {
return {...state, fetching: true};
}
case "FOO_REJECTED": {
return {...state, fetching: false, error: action.payload};
}
case "FOO_FULFILLED": {
return {
...state,
fetching: false,
fetched: true,
data: action.payload,
};
}
}
return state;
};
Still using redux-promises you can do something like this which I think is an elegant way to deal with this problem.
First, set a property in the redux state that will hold any ajax errors that may occurred.
ajaxError: {},
Second, setup a reducer to handle ajax errors:
export default function ajaxErrorsReducer(state = initialState.ajaxError, action) {
if (action.error) {
const { response } = action.payload;
return {
status: response.status,
statusText: response.statusText,
message: response.data.message,
stack: response.data.stack,
};
}
return state;
}
Finally, create a very simple react component that will render errors if there are any (I am using the react-s-alert library to show nice alerts):
import React, { Component } from 'react';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import Alert from 'react-s-alert';
class AjaxErrorsHandler extends Component {
constructor(props, context) {
super(props, context);
this.STATUS_GATE_WAY_TIMEOUT = 504;
this.STATUS_SERVICE_UNAVAILABLE = 503;
}
componentWillReceiveProps(nextProps) {
if (this.props.ajaxError !== nextProps.ajaxError) {
this.showErrors(nextProps.ajaxError);
}
}
showErrors(ajaxError) {
if (!ajaxError.status) {
return;
}
Alert.error(this.getErrorComponent(ajaxError), {
position: 'top-right',
effect: 'jelly',
timeout: 'none',
});
}
getErrorComponent(ajaxError) {
let customMessage;
if (
ajaxError.status === this.STATUS_GATE_WAY_TIMEOUT ||
ajaxError.status === this.STATUS_SERVICE_UNAVAILABLE
) {
customMessage = 'The server is unavailable. It will be restored very shortly';
}
return (
<div>
<h3>{ajaxError.statusText}</h3>
<h5>{customMessage ? customMessage : ajaxError.message}</h5>
</div>
);
}
render() {
return (
<div />
);
}
}
AjaxErrorsHandler.defaultProps = {
ajaxError: {},
};
AjaxErrorsHandler.propTypes = {
ajaxError: PropTypes.object.isRequired,
};
function mapStateToProps(reduxState) {
return {
ajaxError: reduxState.ajaxError,
};
}
export default connect(mapStateToProps, null)(AjaxErrorsHandler);
You can include this component in your App component.
This might not be the best approach but it works for me. I pass the 'this' of my component as var context. Then when i get response back i just execute the methods defined in my components context. In my component i have successHdl and errorHdl. From there i can trigger more redux actions as normal. I checked all the previous answers and seem too daunting for such a trivial task.
export function updateJob(payload, context){
const request = axios.put(UPDATE_SOMETHING, payload).then(function (response) {
context.successHdl(response);
})
.catch(function (error) {
context.errorHdl(error);
});;
return {
type: UPDATE_SOMETHING,
payload: payload,
}
}
Don't use redux-promise. It overcomplicates something that's actually super simple to do yourself.
Instead read the redux docs: http://redux.js.org/docs/advanced/AsyncActions.html
It'll give you a much better understanding of how to handle this kind of interactions and you'll learn how to write something (better than) redux-promise yourself.

Resources