0

My code is as below:

const LOAD = 'redux-example/LOAD';
const LOAD_SUCCESS = 'redux-example/LOAD_SUCCESS';
const LOAD_FAIL = 'redux-example/LOAD_FAIL';
import axios from 'axios';
const initialState = {
    loaded: false
};
export default function info(state = initialState, action = {}) {
    switch (action.type) {

    case LOAD:
    return {
    ...state,
    loading: true
   };
   case LOAD_SUCCESS:
  return {
    ...state,
    loading: false,
    loaded: true,
    data: action.result
  };
case LOAD_FAIL:
  return {
    ...state,
    loading: false,
    loaded: false,
    error: action.error
  };
default:
  return state;
}
}
export function load() {
    return {
        types: [LOAD, LOAD_SUCCESS, LOAD_FAIL],
        promise: (client) => client.get('http://example.com/getdata')
    };
}

I am using https://github.com/erikras/react-redux-universal-hot-example example as starter kit. I want to make promise based api call to example.com/api.But I am not able to do it with async call.I get error in middleware that can not read promise of undefined.My middleware code is as below.

export default function clientMiddleware(client) {
return ({dispatch, getState}) => {
return next => action => {
    if (typeof action === 'function') {
        return action(dispatch, getState);
    }
    const { promise, types, ...rest } = action; // eslint-disable-line no-redeclare
    if (!promise) {
        return next(action);
    }
    const [REQUEST,SUCCESS,FAILURE] = types;
    next({...rest, type: REQUEST});
    const actionPromise = promise(client);
    actionPromise.then(     
        (result) => next({...rest, result, type: SUCCESS}),
        (error) => next({...rest, error, type: FAILURE})
    ).catch((error)=> {
        console.error('MIDDLEWARE ERROR:', error);
        next({...rest, error, type: FAILURE});
    });
    return actionPromise;
};
};
}

MY component code is as below

import React, {Component, PropTypes} from 'react';
import {bindActionCreators} from 'redux';
import {connect} from 'react-redux';
import {load} from 'redux/modules/info';

@connect(state => ({info: state.info.data}),dispatch =>      bindActionCreators({load}, dispatch))

export default class InfoBar extends Component {
static propTypes = {
info: PropTypes.object,
load: PropTypes.func.isRequired
}
render() {
const {info, load} = this.props; // eslint-disable-line no-shadow
const styles = require('./InfoBar.scss');
return (
  <div className={styles.infoBar + ' well'}>
    <div className="container">
      This is an info bar
      {' '}
      <strong>{info ? info.message : 'no info!'}</strong>
      <span className={styles.time}>{info && new Date(info.time).toString()}</span>
      <button className="btn btn-primary" onClick={load}>Reload from server</button>
    </div>
  </div>
);
}
}
user1820017
  • 61
  • 1
  • 2
  • 10
  • I'm afraid you're bumping into same-origin restriction when you perform an asynchronous HTTP request against remote endpoint. Take a look at [public wiki about same-origin circumvention](http://stackoverflow.com/questions/3076414/ways-to-circumvent-the-same-origin-policy), perhaps you'll get an idea how to proxy your requests or overcome the restriction another way. – rishat Nov 29 '16 at 22:41
  • I've used that starter kit, and your code looks correct. I agree with @Rishat above... it looks like you're doing everything right, but you might be making a cross domain REST call that is failing. Do you get any more information in the console after "MIDDLEWARE ERROR" ? – Jeff McCloud Nov 30 '16 at 00:23
  • I don't get cross origin error, but I do get "Cannot read property 'promise' of undefined" error. API works for cross domain access. – user1820017 Nov 30 '16 at 09:06
  • There was error with xhr request which I fixed, but now it works with simple json api as fake data but not with real api call which returns data from database – user1820017 Nov 30 '16 at 11:43
  • Does not work as api request takes time to load, works with simple json – user1820017 Nov 30 '16 at 12:27

1 Answers1

-1

this is only the reducer. You would want to create an action. An action triggers the event that will make the redux store update its state. The basic flow of redux for something like this goes like:

  • Mount a component
  • Dispatch an action
  • Dispatched action in turn will update the store via the Provider component
  • this will trigger a re-render of the component.

The following is a basic example using fetch.

import fetch from 'isomorphic-fetch';

export function getUsers() {
  return dispatch => {
    dispatch({ type: REQUEST_USERS });

    return fetch('/api/v1/users')
      .then(res => res.json())
      .then(users => {
        dispatch({ type: RECEIVE_USERS, payload: users });
        return users;
      });
  }
}

Then you can call this in your component level item.

import { getUsers } from 'actions/users';

class UserList extends Component {
  componentDidMount() { dispatch(getUsers()) }
}

Check out the example

corvid
  • 10,733
  • 11
  • 61
  • 130
  • I am having client middleware which has code above, also with that example If I call on localhost api that works – user1820017 Nov 29 '16 at 20:50
  • but it does not work with the external api call. localhost api has code like this export default function loadInfo() { return new Promise((resolve) => { resolve({ message: 'This came from the api server', time: Date.now() }); }); } – user1820017 Nov 29 '16 at 20:54
  • This is not a proper answer since he is using redux-tunk for middlewares. and breaks the flow – Jose Paredes Nov 30 '16 at 16:36