1

I am still not as fluent in ReactJS, Ant Design, Sagas and Reducers as I thought I am: I am trying to maintain/ debug a single-page app and I am not sure which files I have to adjust and how.

The goal is to add the following <select> in their render() function within component.tsx:

<Select showSearch
        style={{ width: 150 }}
        placeholder="Select entity" 
        // onChange={(e) => { this.handleSelectorChange("Entity", e) }} // to tackle later
        // value={this.props.selectedEntity.toString()}                 // ------ " ------
>
<Option value="0">Option 0</Option>
   {this.props.availableEntities.map((myEntity) =>
    (<Option key={myEntity.Id.toString()}
             value={myEntity.Id.toString()}>{myEntity.Name}</Option>))}
</Select>

In the respective container.tsx, I added:

const mapStateToProps = (state ) => ({
    availableEntities: GeneralSelectors.getAvailableEntities(state),
});

What I get back is the following is only Option 0 instead of all entities (and even on a wrong place), see screenshot

Screenshot of select options

How do I get my selection options dynamically generated using data from an API? Since I do not see backend being called (using the Network tab of my Chrome debugger), I assume something is wrong with the sagas, but that is just an hypothesis.

Background info

For another single-page-app (SPA) of the same project which already has that <select> inside, I found a urls.ts which looks as follows

import UrlMap from "../UrlMap"
import * as Actions from "./actions"
import * as GeneralActions from "../general/actions"

export const urls = [
    new UrlMap("myWorkingSPA",
        () => [
            Actions.load(),
            GeneralActions.loadEntities(),
            Actions.loadDifferencePositions()
        ])
];

I don't know where this file is actually called, and what I have to modify where in order to include it.

In the respective actions.ts of the running SPA I find

export function loadEntities() : Action {
    return {
        type: LOAD_ENTITIES
    }
}

I am not sure whether my SPA is also taking this actions.ts or not.

The sagas.ts is the same for the running SPA and for my component:

function* loadEntities() {
    const url = config.apiBaseUrl + "/api/Entities";

    try {
        const response: Response = yield fetch(url);
        const json: Interfaces.Entity[] = yield response.json();
        yield put(Actions.setEntities(json));
    } catch (e) {
        notification.error({ message: "Error", description: "Error loading Entities" });
    }
}

function* watchLoadEntities() {
    yield takeEvery(Actions.LOAD_ENTITIES, loadEntities);
}

Hope that was not too much information, but I guess it is all related to the problem.

References

Community
  • 1
  • 1
B--rian
  • 5,578
  • 10
  • 38
  • 89
  • 1
    "I assume something is wrong with the sagas, but that is just an hypothesis." I'd say that this might be a correct hypothesis. This selector `GeneralSelectors.getAvailableEntities(state)` should create the slice of the store you need to populate your ``. If you track it down, you might find the correct actions that should be dispatched to get your info. As for the other `` component, is the call made during the application startup? When a specific component mounts? Finding _when_ the call is actually made might help you. – Clafouti Feb 20 '20 at 08:58
  • @Clafou: I wrote an answer instead. Feel free to comment. – B--rian Feb 20 '20 at 09:21

1 Answers1

1

Eventually I also found another sagas.ts which was also in effect:

function* parseUrl({ payload }) {
    const pathName = payload.location.pathname;

    const myComponentURI: match<{}> = matchPath(pathName, { path: config.uiBaseUrl + "myComponent" });
    if (myComponentURI) {
        yield put(GeneralActions.loadEntities()); // <---
    }

   // ... here are many more const. for various different pages
}

The GeneralActions refers to an actions.ts in a directory general.

I solved the issue by putting the marked line. Warning: I believe, this is not the way things should be implemented, I am just saying that it hot-fixed my issue.

As clafou pointed out in a comment, the clean way would be to trigger the yield on startup.

B--rian
  • 5,578
  • 10
  • 38
  • 89
  • 1
    I don't really know the way your application works so it might totally be correct to do it that way. Using a saga to dispatch some actions in response to another action seems completely normal to me (disclaimer : I'm not a redux-saga expert). Glad you could find a solution to your issue! :) – Clafouti Feb 20 '20 at 09:25