salsita / prism

React / Redux action composition made simple http://salsita.github.io/prism/
496 stars 24 forks source link

Get currentUser state in component Updater #68

Closed dgsunesen closed 7 years ago

dgsunesen commented 7 years ago

Hi,

So I have the following in my boilerplate file:

const reducers = combineReducers({
      root: updater,
      routing: routerReducer,
      user: userReducer,
      form: formReducer
    });

Where user contains the currentUser logged in. How would I access that users property in a redux-elm components Updater?.. I have a saga in an Updater that needs the users id in order to call an endpoint in there.

In my components Updater I want to be able to do something like the following:

function* fetchLocations (): IterableIterator<Effect> {
  try {
    yield put( getLocations() );
    const locations = yield call(loadLocations, "http://myApiEndpoint/" + userId + "/locations");
    yield put( receiveLocations(locations) );
  }
  catch (error) {
    console.log(error.message, error.name);
    yield put( errorHandlerLocations(error));
  }
}

Where userId is the id from the currentUser logged in.

Best regards, Dan

tomkis commented 7 years ago

I suppose your fetchLocations is being executed when some actions kicks in, right? You might want to keep the userId in the payload of the action so that you can easily pass it to fetchLocations saga.

dgsunesen commented 7 years ago
declare function require(name: string): any;

import { takeEvery } from "redux-saga";
import { take, put, call, fork, select, Effect } from "redux-saga/effects";
import { getRoles, receiveRoles, errorHandler, getLocations, receiveLocations, errorHandlerLocations } from "./actions";
import { loadRoles, loadLocations } from "./effects";
import { Map } from "immutable";
import { GET_ROLES, RECEIVE_ROLES, GET_LOCATIONS, RECEIVE_LOCATIONS } from "./actions";

const { Updater } = require("redux-elm");

// Switch this for users account id
const tempAccountId: number = 3;

// Initial immutable model/state passed to the Updater.
type Init = Map<string, any>;
export const init: Init = Map({
  isGettingRoles: false,
  isGettingLocations: false
});

function* fetchRoles (): IterableIterator<Effect> {
  try {
    yield put( getRoles() );
    const roles = yield call(loadRoles, "https://pathToApiEndpoint/api/Roles");
    yield put( receiveRoles(roles) );
  }
  catch (error) {
    console.log(error.message, error.name);
    yield put( errorHandler(error));
  }
}

function* fetchLocations (): IterableIterator<Effect> {
  try {
    yield put( getLocations() );
    const locations = yield call(loadLocations, "pathToApiEndpoint/" + tempAccountId + "/locations");
    yield put( receiveLocations(locations) );
  }
  catch (error) {
    console.log(error.message, error.name);
    yield put( errorHandlerLocations(error));
  }
}

function* locationSaga() {
  yield* fetchLocations();
}

// Main saga passed to the Updater.
function* saga() {
  yield fork(locationSaga);
  yield* fetchRoles();
}

export default new Updater(init, saga)
  .case(GET_ROLES, model => model.set("isGettingRoles", true))
  .case(RECEIVE_ROLES, (model, {roles}) =>
    model
      .set("isGettingRoles", false)
      .set("roles", roles))
  .case(GET_LOCATIONS, model => model.set("isGettingLocations", true))
  .case(RECEIVE_LOCATIONS, (model, {locations}) =>
    model
      .set("isGettingLocations", false)
      .set("locations", locations))
  .toReducer();

So I'm getting locations once I enter the route with this component.

tomkis commented 7 years ago

Closing because of irrelevance. prism v4 does not deal with Sagas anymore.