How to use POST method to list data in RA - react-admin

I have tried to use ra-jsonapi-client to make POST call to my api and list retrieved data. Is it possible? My code is
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import { Admin, Resource, ListGuesser } from 'react-admin';
const dataProviders = [
{ dataProvider: jsonapiClient('http://my.api.com:1234'), resources: ['get_info'] }]
const App = () => (
<Admin dataProvider={dataProviders}>
<Resource name="get_info" list={ListGuesser} />
</Admin>
);
export default App;
I know how to pass resource to dataprovider, but I can't figure out how to pass data and type in Resource. Is it possible or I need to write my own dataprovider?
I am pretty new to RA.
Thank you

You need to write your own custom data provider. A data provider abstracts the details of your API away from react-admin.
React admin doesn't care what you need to do to get data from your API.

Related

Missing keys issue in i18next with only one React Component

I am developing a react-project with multilingual (en and fr). Everything is working fine and I am able to translate my app from en to fr and vice versa. The translations are working when refreshing the page too.
I have one React Component that is unable to translate and is showing a missing key error.
i18next::translator: missingKey fr translation CampaignDetails.description CampaignDetails.description
Instead of translating the text for description, it is showing me CampaignDetails.description exactly
PROBLEM EXPLANATION
Go to this URL http://donatenow-9cc92.web.app/
Try changing the language at the rightside of the header. It will work.
There is a search field at the leftside in the header. Search for "mervice" and wait until the
charity shows up
You can see a card for the searched charity, click on the card anywhere but not on follow
button
The URL now looks like this https://donatenow-9cc92.web.app/mervice
Try changing the language now and it will work too.
Refresh this page https://donatenow-9cc92.web.app/mervice and you will see the translations
are still working
Now scroll this page https://donatenow-9cc92.web.app/mervice and at the bottom, you will see
some campaigns like 'Sadqah', 'Zakat' and 'Dollar a Day for Sadaqa'. Click on any campaign,
lets say you have clicked 'Sadqah'
Now the URL is something like this https://donatenow-9cc92.web.app/mervice/sadqah
Try changing the language from this route and it will work fine
The problem is if you click on this link https://donatenow-9cc92.web.app/mervice/sadqah
directly or refresh the page. The translation will not work and the console will give you
missing keys error
EXPLANATION TO POINT 11
1- I have a NotFound.js component in which I am checking if the URL has any charity name like mervice. For example, if the URL is like this domainName/mervice then I am extracting the mervice from the URL and doing a Axios call to fetch the charity and then navigating to the charity page
https://donatenow-9cc92.web.app/mervice (The translations are working no matter if the user has come directly to the page or He/She searched for the charity)
2- In the same function of NotFound.js in which I am fetching the charity, I am also fetching the campaign for the charity. I am checking if the URL is like this domaninName/mervice/campaign and then if the campaign is found for the charity (mervice in this case) then I am navigating to the campaign page.
3- https://donatenow-9cc92.web.app/mervice/sadqah (The translation will not work if you click on this link directly but translations will work if you do it manually like using the search field)
If the translation is working for this page https://donatenow-9cc92.web.app/mervice then why it is not working for this page https://donatenow-9cc92.web.app/mervice/sadqah
The component is the same, I am only navigating in this component based on the condition
Index.js
import React, { Suspense } from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import "./css/Auth.css";
import "./css/SearchOrganization.css";
import "./css/Profile.css";
import "./css/Donations.css";
import "./css/ReceiptModal.css";
import "./css/Recurring.css";
import { Provider } from "react-redux";
import i18n from "i18next";
import { initReactI18next } from "react-i18next";
import LanguageDetector from "i18next-browser-languagedetector";
import HttpApi from "i18next-http-backend";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
import store from "./redux/store";
const root = ReactDOM.createRoot(document.getElementById("root"));
i18n
.use(initReactI18next)
.use(LanguageDetector)
.use(HttpApi)
.init({
debug: true,
supportedLngs: ["en", "fr"],
fallbackLng: "en",
detection: {
order: ["localStorage"],
caches: ["localStorage"],
},
backend: {
loadPath: "assets/locales/{{lng}}/translation.json",
},
interpolation: {
escapeValue: false,
},
});
root.render(
<Suspense fallback={null}>
<React.StrictMode>
<Provider store={store}>
<App />
</Provider>
</React.StrictMode>
</Suspense>
);
reportWebVitals();
NotFound.js
axios
.get(`${hostName}api/v1/search/organization?name=${lowercase}&type=shortName`)
.then((res) => {
if (res.data.data.length > 0) {
// setting states
setLoader(false);
setError("");
// local storage
localStorage.setItem("organization", JSON.stringify(res.data.data[0]));
// setting props
setOrganizationDetails(res.data.data[0]);
// setting organization path
const data = res.data.data[0];
const organizationName = data.shortName;
const cleanOrganizationName = organizationName.replace(
/[^a-zA-Z0-9]/g,
""
);
setOrganizationPath(cleanOrganizationName.toLowerCase()); // redirects to charity translation is working
// fetching campaign for the given organization
for (let i = 0; i < data.campaigns.length; i += 1) {
const word = data.campaigns[i].name.replace(/[^a-zA-Z0-9]/g, "");
const lowercase = word.toLowerCase();
if (secondString === lowercase) {
setCharityPath(lowercase); // redirects to campaign, translation not working
setCharityDetails(data.campaigns[i]);
localStorage.setItem("campaign", JSON.stringify(data.campaigns[i]));
break;
} else {
setCharityPath(null);
setCharityDetails(null);
localStorage.removeItem("campaign");
}
}
}
});

How to use hooks in custom plugins

I am trying to write a custom plugin for our Docusaurus site. I am able to wire up the custom component, but I cannot use hooks like useState or useEffect. The page crashes saying I'm using an invalid React hook.
I know its possible to use hooks because I see other plugins doing it so I'm sure its a syntax problem somewhere.
Here's my code:
index.ts
import path from 'path'
module.exports = function () {
return {
name: 'docusaurus-theme-myorg-technology',
getThemePath() {
return path.resolve(__dirname, './theme')
}
};
};
theme/index.tsx
import React from 'react'
import {CustomTOC} from './CustomTOC'
const WrappedTOC = (props: any) => {
return (
<CustomTOC {...props} />
);
};
export default WrappedTOC;
theme/CustomTOC.tsx
import React, { useState } from 'react';
import TOC from '#theme-init/TOC';
export default function CustomTOC(props: any) {
//const [tags, setTags] = useState<any[]>([]); <-- if I comment this out the page crashes
return (
<>
<TOC {...props} />
Hello world
</>
);
}
"Invalid hooks call" link to a doc page, that you should read carefully.
Most likely: you are using a different version of React for your component lib that the one Docusaurus uses internally, and it leads to the React lib being used twice at runtime. Make sure the final project will only include one React version. You can for example use the exact same version that the one Docusaurus uses

How to create and use custom APIs in Spartacus storefront?

We have a custom API created in hybris and I need to use the data returned by that custom API in some Spartacus pages. I want to do this post login and want to call that api whenever the page refreshes.
Also I want to maintain the data in a state so that I can use it across the pages.
I know how to do it in Angular but I am confused how to do it in Spartacus. Can someone please help me
You should treat spartacus as external lib. If you know how implement it in Angular, just do it. Most of our actions like login are exported in public API:
import { ActivatedRouterStateSnapshot, AuthActions } from '#spartacus/core';
import { RouterNavigatedAction, ROUTER_NAVIGATED } from '#ngrx/router-store';
#Injectable()
export class YourEffects {
#Effect()
yourActionOnLogin$: Observable<YourActions.XXX> = this.actions$.pipe(
ofType(AuthActions.LOGIN),
map(() => new CheckoutActions.XXX())
);
#Effect()
yourActionOnNavigation$: Observable<YourActions.YYY> = this.actions$.pipe(
ofType<RouterNavigatedAction<ActivatedRouterStateSnapshot>>(
ROUTER_NAVIGATED
),
map(() => new YourActions.YYY())
);
}
You can create and provide own modules for part of ngrx store and occ adapters (API) as well.

Is is possible to use a custom notification library in react-admin instead of the built-in notifications? [duplicate]

How could i make react-admin to show a multi-line notification / error message on the snackbar?
Having the following dataProvider:
export default (type, resource, params) => {
throw new Error(`
Message line 1.
Message line 2.
Message line 3.
`);
};
That shows a single line message when loading a List component:
error notification screenshot
UPDATE 2022:
Since version 4 of react-admin, you can tell the useNotify hook, to use a multi line message passing the multiLine prop: https://marmelab.com/react-admin/useNotify.html#:~:text=multiLine%3A%20Set%20it%20to%20true%20if%20the%20notification%20message%20should%20be%20shown%20in%20more%20than%20one%20line.
End of UPDATE.
Ok, with the help of the docs I manage to do what I wanted.
Defining a custom Layout component to be used by the App component and passing it a custom Notification component.
// ./MyLayout.js
import React from 'react';
import { Layout } from 'react-admin';
import MyNotification from "../MyNotification";
const CustomLayout = props => (
<Layout {...props} notification={MyNotification} />
);
export default CustomLayout;
Then I pass a custom CSS class to the Notification component.
// ./MyNotification.js
import React from 'react';
import {withStyles} from '#material-ui/core/styles';
import {Notification} from 'react-admin';
// Allow multi-line messages to be displayed
const cssMsg = {
snackbarContent: {
whiteSpace: 'pre-wrap'
}
};
const MyNotification = withStyles(cssMsg)(({classes, ...props}) => (
<Notification {...props} className={classes.snackbarContent}/>
));
export default MyNotification;
error notification screenshot multi-line

Retrieving data from Meteor server

I am trying a hello world app using react-native, Meteor and xvonabur/ react-native-meteor.
I am trying to subscribe to the data from MongoDB.
server code :
import {Mongo} from 'meteor/mongo';
import {Meteor} from 'meteor/meteor';
export const Pokemon = new Mongo.Collection('pokemon');
Meteor.publish('pokemon', () => {
return Pokemon.find({});
});
Client code:
export default createContainer(params=>{
Meteor.subscribe('pokemon');
return{
pokemon: Meteor.collection('pokemon').find({})
};
}, PokeMap);
As I understood after reading previous posts on stackoverflow, I have to define export const Pokemon = new Mongo.Collection('pokemon'); in a common scope to both server and the client. My client and the server are in Two different folders.
I tried to import pokemon.js in to the client as follow,
import { Pokemon } from '../../pokeserver/imports/collections/pokemon.js'
and tried to use it as follow;
export default createContainer(params=>{
Meteor.subscribe('pokemon');
return{
pokemon: Pokemon.find({}),
};
}, PokeMap);
But I am getting following error,
undefined Unable to resolve module `../../pokeserver/imports/collections/pokemon.js` from `Src\PokeMap.js`:
I think your import is wrong. You are doing an export default, which means that you don't need the brace around Pokemon
import Pokemon from '/imports/collections/pokemon.js'
Should do the trick