Get data from API with Redux, NextJS and SSR - javascript

I am using next-redux-wrapper, and i can get data to server store, but i cant send it to client store.
My code looks like this:
In /pages/index:
export const getServerSideProps = wrapper.getServerSideProps(async (ctx) => {
ctx.store.dispatch(testFunc(ctx));
return {props: {data: ctx.store.getState().test.data}}
})
In store/../action:
export const testFunc = (ctx) => (dispatch) => {
return fetch(url)
.then(r => r.json())
.then(r => {
const data = r;
dispatch({type: actionTypes.DATA, data});
})
}
How can i do it right?

Related

remove the TMDB API

I am currently working with a clone of a streaming platform, it turns out that this clone has the TMDB API integrated and I want to remove it to store the objects returned by this api in a firebase database, but I am a little confused.
In my Firebase file, I have a promise that returns an array of objects and it looks like this:
export const getGamesDocument = () => {
return new Promise((resolve, reject) => {
const documents = [];
firestore
.collection("games")
.get()
.then((snapshot) => {
snapshot.forEach((doc) => {
const documentData = doc.data();
documentData.id = doc.id;
documents.push(documentData);
});
resolve(documents);
})
.catch((error) => {
reject(error);
});
});
};
So far everything is going well where I am getting confused is in this redux code since I have no knowledge of the subject:
export const fetchAdventureMoviesRequest = () => ({
type: moviesActionTypes.FETCH_ADVENTURE_MOVIES_REQUEST,
});
export const fetchAdventureMoviesSuccess = (adventureMovies, isPage) => ({
type: isPage
? moviesActionTypes.FETCH_ADVENTURE_MOVIES_SUCCESS
: moviesActionTypes.LOAD_MORE_ADVENTURE_MOVIES_SUCCESS,
payload: adventureMovies,
});
export const fetchAdventureMoviesFailure = error => ({
type: moviesActionTypes.FETCH_ADVENTURE_MOVIES_FAILURE,
payload: error,
});
export const fetchAdventureMoviesAsync = (fetchUrl, isPage) => {
return dispatch => {
dispatch(fetchAdventureMoviesRequest());
axios
.get(fetchUrl)
.then(res => {
const adventureMovies = res.data.results.map(el => ({
...el,
isFavourite: false,
}));
if (isPage) {
dispatch(fetchAdventureMoviesSuccess(adventureMovies, isPage));
} else dispatch(fetchAdventureMoviesSuccess(adventureMovies));
})
.catch(error => {
const errorMessage = error.message;
dispatch(fetchAdventureMoviesFailure(errorMessage));
});
};
};
I want to remove the array of objects that are obtained in the constant "adventureMovies" and replace it with the array of objects that I obtain in the aforementioned promise.

How to change a query value on an api call based on Redux

I have this issue that i do not know how to figure it out, this action.js is doing an api call to my app from weatherApi, what I need is make a button to change cityName value to another as 'madrid' for example, another button to change lang value. How could i do it from app.js or can I get it done on the same file action.js
const appid = 'randomapi';
const cityName = 'london';
const lang = 'en';
export const fetchData = () => {
return (dispatch) => {
return fetch(`https://api.openweathermap.org/data/2.5/weather?q=${cityName}&lang=${lang}&appid=${appid}`)
.then(response => response.json())
.then(json => dispatch(
{ type: "FetchData", data: json }))
.catch(err => dispatch(
{ type: "ERROR",msg: "Unable to fetch data" }))
}
}

trying to fetch data with fetch and promise, doesnt work (react)

Im trying to get data out of an API with fetch, i can console.log the result in the fetch but out of the fetch i cant reach the data.
So i got this fetchData.js file with the function in it:
export const fetchData = (url) => {
return fetch(url)
.then(response => response.json())
.then(result => console.log(result))
.catch(error => console.log('error', error))
}
and then in the app.jsx file i call the function like this:
import { fetchData } from "./fetchData";
const URL = "https://pokeapi.co/api/v2/pokemon"
function App() {
let data = fetchData(URL);
console.log(data);
//return etc
But the console.log(data) keeps saying "undefined"
Can somebody please help me ?
You have to wait for the asynchronous action to complete before logging it.
let data = fetchData(URL).then(() => {console.log(data);});
(also either remove then(result => console.log(result)) or return result from it)
fetchData is an async function, that is why the console.log is executed before fetchData is resolved:
export const fetchData = async (url) => {
return fetch(url)
.then(response => response.json())
.then(result => (result)) //--> data
.catch(error => console.log('error', error))
}
then in component, inside useEffect:
function App() {
const [data, setData] = useState([]) //--> keep data in component state
useEffect(()=> {
fetchData(URL) //--> fetch data when component is mounted
.then(response => setData(response))
}, []);
//...
}

Using RxJS and axios, how do you fetch data onClick in React component?

I'm struggling with how to fetch data using RxJS and axios onClick in a React component. But getting closer, I think. Any attempts I've tried either run when component mounts, not onClick, or don't run at all even onClick.
Basically, how to call onClick and how to pass a payload. There just seems to be nothing online to explain this which i would expect to be a common situation.
const MyComponent = () => {
const [data, setData] = useState(null);
const getData$ = new Subject(observer => {
axios
.post(`/my-url/`, **how to get payload to here**)
.then(response => {
observer.next(response.data);
observer.complete();
})
.catch(error => {
observer.error(error);
});
});
useEffect(() => {
const subs = getData$.subscribe({
next: res => setData(res),
});
return () => subs.unsubscribe();
}, []);
return (
<Button onClick={() => getData$.next(payload)} />
);
};
Any help appreciated.
you can pass in the payload in getData like this
const getData$ = (payload) => new Subject(observer => {
axios.post(`/my-url/`, payload)
.then(response => {
observer.next(response.data);
observer.complete();
})
.catch(error => {
observer.error(error);
});
});
This basically just creates an anonymous function called getData that returns your Subject. It's equivalent to this:
const getData$ = function (payload) {
return new Subject(observer => {
axios.post(`/my-url/`, payload)
.then(response => {
observer.next(response.data);
observer.complete();
})
.catch(error => {
observer.error(error);
});
});
};

Proper way to call two async action

How to call an async action after another action was successfully dispatched?
I am learning Redux and I have some questions, about async action.(I am using thunk)
I have two action:
export const addToCart = addToCartData => dispatch => {
axios.post("/api/cart/add-to-cart", {addToCartData)
.then(res => {
dispatch({ type: ADD_TO_CART, payload: res.data });
})
.catch(err => console.log(err));
};
export const removeProduct = (userID) => dispatch => {
axios
.delete(`/api/wait-list/remove/${userID}`)
.then(res => {
dispatch({ type: REMOVE_FROM_WAITLIST, payload: res.data });
})
.catch(err => console.log(err));
};
And I want to execute removeProduct action only after addToCart will be successfully executed! I am trying to do third one with two of them, it looks like this:
export const addToCartAndPemoveProduct = (data) => dispatch => {
dispatch(addToCart(data)
dispatch(removeProduct(data));
But it executes removeProduct action first, and after addToCart....
How do I can do it right due to order? Maybe I should return a promise from first one and execute second one after it will be successfull resolve? It will be looking like this:
export const addToCart = addToCartData => dispatch => {
return axios.post("/some", {addToCartData)
.then(res => { dispatch({ type: ADD.....})
};
export const addToCartAndPemoveProduct = (data) => dispatch => {
dispatch(addToCart({ userID, productId }))
.then(data => {
dispatch(removeProduct({ userID, productName, productDescr }));
})
}
Is it ok or not?
Do you always want to dispatch removeProduct after addToCart? In this case:
export const addToCart = addToCartData => dispatch => {
// You'll have to get the userId here first, probably from getState() if it's not being passed in.
axios.post("/api/cart/add-to-cart", {addToCartData)
.then(res => {
dispatch({ type: ADD_TO_CART, payload: res.data });
dispatch(removeProduct(userId));
})
.catch(err => console.log(err));
};
Maybe rename the action to moveProductFromWaitListToCart to express the full transaction.

Categories