30

I am a beginner with reactjs/redux, could not find a simple to use example of how to use an api call to retrieve data in a redux app. I guess you could use a jquery ajax call but there are probable better options out there?

2

2 Answers 2

53

JSfiddle; http://jsfiddle.net/cdagli/b2uq8704/6/

It uses redux, redux-thunk and fetch.

Fetch methods;

function fetchPostsWithRedux() {
    return (dispatch) => {
    dispatch(fetchPostsRequest());
    return fetchPosts().then(([response, json]) =>{
        if(response.status === 200){
        dispatch(fetchPostsSuccess(json))
      }
      else{
        dispatch(fetchPostsError())
      }
    })
  }
}

function fetchPosts() {
  const URL = "https://jsonplaceholder.typicode.com/posts";
  return fetch(URL, { method: 'GET'})
     .then( response => Promise.all([response, response.json()]));
}

Actions used above:

(Note: You can define many actions e.g. fetchPostRequest can be used to display a loading indicator. Or you can dispatch different actions in case of different HTTP status codes.)

function fetchPostsRequest(){
  return {
    type: "FETCH_REQUEST"
  }
}

function fetchPostsSuccess(payload) {
  return {
    type: "FETCH_SUCCESS",
    payload
  }
}

function fetchPostsError() {
  return {
    type: "FETCH_ERROR"
  }
}

And in your reducer you can load the posts to state;

const reducer = (state = {}, action) => {
  switch (action.type) {
    case "FETCH_REQUEST":
      return state;
    case "FETCH_SUCCESS": 
      return {...state, posts: action.payload};
    default:
      return state;
  }
} 

You can access the state and actions within your component after connecting them with;

connect(mapStateToProps, {fetchPostsWithRedux})(App);
Sign up to request clarification or add additional context in comments.

2 Comments

Weird, using this exact code i'm getting Uncaught (in promise) Error: Reducers may not dispatch actions.
What does returning Promise.all([response, response.json()]) do? Why not return response.json()?
11

Create an action where you perform the request to your API. You can use a library like axios or fetch which return a promise.

actions/index.js:

import axios from 'axios';

export const FETCH_SOMETHING= 'FETCH_SOMETHING;
const ROOT_URL = 'http://api.youapi.com';

export function fetchWeather(city) {

    const url = `${ROOT_URL}&q=${aParamYouMayNeed}`;
    const request = axios.get(url);

    return {
        type: FETCH_SOMETHING,
        payload: request
    };
}

Then in a reducer, consume the promise result once resolved as follows:

reducers/reducer_something.js:

import { FETCH_SOMETHING} from '../actions/index';

export default function(state = [], action) {
    switch (action.type) {
        case FETCH_SOMETHING:
        return [ action.payload.data, ...state ];
    }

    return state;
}

Code borrowed from Stephen Grider. This is his repo: https://github.com/StephenGrider/ReduxCasts/tree/master/weather/src

4 Comments

Do you have a plunker or something?
No, but you can clone the sample in myresponse (just edited it) that I have tested and works fine.
How come you don't need to use .then() in the reducer to make sure the Promise has been fulfilled and that data isn't undefined?
@jhuang good question. I forgot to mention when I said "consume the promise result once resolved as follows" that the example provided by Stephen Grided, uses a library called redux-promise which has to be applied in the entry point as follows: applyMiddleware(ReduxPromise)(createStore); That library deals with promises making your code cleaner. npmjs.com/package/redux-promise

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.