4

I'm trying to use <ReferenceInput> element with custom dataProvider and getting this error:

Missing translation for key: "dataProvider is undefined"

It happens even if my data provider looks like this:

import jsonServerProvider from "ra-data-json-server";
import { adminPageTokenFetch } from "APIServices/CRUD";

const dataProvider = jsonServerProvider("/api", adminPageTokenFetch);

export const myDataProvider = {
  ...dataProvider
}

Example of component using <ReferenceInput>:

export const SessionEdit = (props: any) => {
  return (
    <Edit {...props}>
      <SimpleForm>
        <ReferenceInput source="film" reference="films">
          <SelectInput optionText="name" />
        </ReferenceInput>
        <DateInput source="dateTime" />
        <NumberInput source="price" />
        <ReferenceInput source="genre" reference="genres">
          <SelectInput optionText="name" />
        </ReferenceInput>
      </SimpleForm>
    </Edit>
  );
};

Here is my index page:

export const AdminPage = (props: { lang: string }) => {
  const messages = {
    ru: russianMessages,
    en: englishMessages
  } as any;

  return (
    <Provider store={createAdminStore({ myDataProvider, history })}>
      <Admin
        dataProvider={myDataProvider}
        history={history}
        title={props.lang === "ru" ? "Админ панель" : "My admin"}
        i18nProvider={polyglotI18nProvider(() => messages[props.lang])}
      >
        <Resource
          name="sessions"
          list={SessionList}
          edit={SessionEdit}
          create={SessionCreate}
        />
        <Resource name="translations" list={TranslationList} />
      </Admin>
    </Provider>
  );
};

And here is createAdminStore function:

export default ({ dataProvider, history }: any) => {
  const reducer = combineReducers({
    admin: adminReducer,
    router: connectRouter(history)
  });

  const saga = function* rootSaga() {
    yield all([adminSaga(dataProvider)].map(fork));
  };
  const sagaMiddleware = createSagaMiddleware();

  const store = createStore(
    reducer,
    compose(applyMiddleware(sagaMiddleware, routerMiddleware(history)))
  );
  sagaMiddleware.run(saga);
  return store;
};

There is how it looks on the UI:

UI Error message

Other components still work fine.

  • We need to look closely at your `translation` files. Could you share part of those? – MwamiTovi Mar 21 '20 at 14:21
  • @MwamiTovi , Do you mean components I pass in `admin` component? If so, I've edited my question. – Spider Qshka Mar 22 '20 at 13:40
  • This error seems to be originating from `translation` linked to the `dataProvider`. I think it might be more helpful to share files linked to those. Maybe share files where you are using your customized `myDataProvider` – MwamiTovi Mar 22 '20 at 13:54
  • @MwamiTovi, I'm using `createAdminStore` function and passing it's result to `admin` component. Just added all this stuff to the question. – Spider Qshka Mar 22 '20 at 15:32
  • From your code, you are working with `changing locale (language) at Runtime`. Kindly update this line `i18nProvider={polyglotI18nProvider((locale) => messages[locale])}` within . Let me know what happens. – MwamiTovi Mar 22 '20 at 15:54
  • @MwamiTovi, didn't help, actually this problem appears without using `changing locale` at all. – Spider Qshka Mar 23 '20 at 05:15
  • Been debugging this error. Quick question, does this `error` prevent your app from running? Or does your app run well, but logs this error to the console? – MwamiTovi Mar 25 '20 at 03:39
  • @MwamiTovi, app doesn't crash, just logs the error while using `referenceInput`. – Spider Qshka Mar 25 '20 at 06:16
  • I suspected that too. I have gotten that error too a couple of times, and it requires suppressing. Let me post an answer below, since it can't really fit here. – MwamiTovi Mar 25 '20 at 06:50

2 Answers2

1

By default, the polyglotI18nProvider logs a warning in the console each time it's called with a message that can’t be found in the current translations.

To avoid this for some messages, e.g. error messages from a data source you don’t control (like a web server), we can add use the allowMissing option to Polyglot at initialization.
Read about react-admin translations here.

// Here, we seem to be missing the complete base url
- const dataProvider = jsonServerProvider("/api", adminPageTokenFetch);

// For dataProvider to be defined, provide the complete base url
+ const dataProvider = jsonServerProvider("http://path.to.my.api", adminPageTokenFetch);

// Add the "allowMissing" option
i18nProvider={polyglotI18nProvider(() => messages[props.lang], {allowMissing: true} )}
MwamiTovi
  • 2,425
  • 17
  • 25
  • To further your understanding of this concept, you can [read more directly from polygot.js](https://airbnb.io/polyglot.js/#options-overview). – MwamiTovi Mar 25 '20 at 07:09
  • it seems that now message doesn't appear in console, but there is still a pop-up with the error and `referenceInput` still doesn't load any data passed in it. Adding the screenshot of the warning pop-up to the question. – Spider Qshka Mar 25 '20 at 07:41
  • Kindly see my updated answer. Thanks. But am still confused why even when you just used `/api` the other components were working fine! – MwamiTovi Mar 25 '20 at 07:48
  • I'm using proxy in my app, but still, why does it work in one component and doesn't in another one?) – Spider Qshka Mar 25 '20 at 08:53
  • Good question: Why work and fail here? Issue then seems to be with your proxy. OMG, had missed this - in your ``, you are using `film` and `genre`, they must be added as `` within `` because your app attempts to fetch them when referenced. That should clear our problem. Had you done that? – MwamiTovi Mar 25 '20 at 08:59
  • Yea, they are, I just didn't add it into the question description. Sorry for that simplification, SO forced me not to use code a lot – Spider Qshka Mar 25 '20 at 16:58
0

Don't know exacly how does it work, but it seems after changes below referenceInput forks fine:

...
<Provider
      store={createAdminStore({
        dataProvider: Object.assign(myDataProvider),
        history
      })} // changed from createAdminStore({ myDataProvider, history })
    >
    <Admin
        dataProvider={Object.assign(myDataProvider)} // changed from dataProvider={myDataProvider}
        history={history}
        title={props.lang === "ru" ? "Админ панель" : "My admin"}
        i18nProvider={polyglotI18nProvider(() => messages[props.lang])}
    >
        ...
    </Admin>
</Provider>