Get API response from redux store and send response - javascript

What i want to execute is do a post request and access the res.json() and taking res.json() i want to dispatch a action to update the store and access response object in the component.A small code example will be great.
export const filesDownload = (postData) => dispatch =>{
console.log(postData);
fetch('http://'+ip+':8000/api/v1/integrator/email/need_attachment/',{
method:'POST',
headers: {
'content-type': 'application/json'
},
body : JSON.stringify(postData)
})
.then(res => console.log(res.json()))
.then(files => dispatch({
type: GET_FILES,
payload:files
}))
}
I want to dispatch the res.json() to the store .

Try axios its cleaner:
export const filesDownload = (postData) => dispatch =>{
console.log(postData);
axios.post('http://'+ip+':8000/api/v1/integrator/email/need_attachment/')
.then((response)=>response.data)
.then((files)=>dispatch({
type: GET_FILES,
payload:files
}))
.catch((err)=>console.log(err))
}
If it's not working, you will have to use redux Thunk, tell me, I will help you

Related

How to use the value of a response from a GET request once the request is finished in React? [duplicate]

I am new to React and API request calls.
I have created a basic React App. I have a requirement to display the data by calling an API.
I am able to retrieve the data in the console, but finding difficult to display it on the browser.
Here is the data which I need to display :
Console Data
Here is the code that I have written (generated from Postman):
import React from "react";
class FetchRandom extends React.Component {
render() {
var myHeaders = new Headers();
myHeaders.append(
"Authorization",
"Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik1yNS1BVWliZkJpaTdOZDFqQmViYXhib1hXMCIsImtpZCI6Ik1yNS1BVWliZkJpaTdOZDFqQmViYXhib1hXMCJ9.eyJhdWQiOiIwMDAwMDAwMy0wMDAwLTBmZjEtY2UwMC0wMDAwMDAwMDAwMDAvY29vcG9ubGluZS5zaGFyZXBvaW50LmNvbUA4MzRmYjdiNC02MjRkLTRkZTgtYTk3Ny0yZDQ2YWQ5NzliZDkiLCJpc3MiOiIwMDAwMDAwMS0wMDAwLTAwMDAtYzAwMC0wMDAwMDAwMDAwMDBAODM0ZmI3YjQtNjI0ZC00ZGU4LWE5NzctMmQ0NmFkOTc5YmQ5IiwiaWF0IjoxNjQ1MDg1NjQ3LCJuYmYiOjE2NDUwODU2NDcsImV4cCI6MTY0NTE3MjM0NywiaWRlbnRpdHlwcm92aWRlciI6IjAwMDAwMDAxLTAwMDAtMDAwMC1jMDAwLTAwMDAwMDAwMDAwMEA4MzRmYjdiNC02MjRkLTRkZTgtYTk3Ny0yZDQ2YWQ5NzliZDkiLCJuYW1laWQiOiJhMDFkNGE5Yi1mZGE2LTQ2ZTQtOTE3NC02NjFhNjY3M2FjZGNAODM0ZmI3YjQtNjI0ZC00ZGU4LWE5NzctMmQ0NmFkOTc5YmQ5Iiwib2lkIjoiMGU4ZDY3NjQtM2JjNS00MDg2LTgxOGUtZGU3N2VlODYyOTc4Iiwic3ViIjoiMGU4ZDY3NjQtM2JjNS00MDg2LTgxOGUtZGU3N2VlODYyOTc4IiwidHJ1c3RlZGZvcmRlbGVnYXRpb24iOiJmYWxzZSJ9.ge789TPniLEXtK_2zuMqZzOgLM6z1arpC5CEDAGB9J3VoEllwKCEXtlL-jzCo45aLD6VOanIbWUugdFuGXeBgeuCSV9PYRGSX9qmf5sWWvGqGM3InLq6-xHtUUE56cq9EQI634jfytq8XhUO3uLXj9x3J5rumY4WH1E0LEivCCy2A02iGmxFHsa6uTC1Iy1K_wJ4jIqlf3KRU8h0rO6HSmx2uPDeVM7KtMRFanWMgYrGUzBIk5Yh-kFCfdXFftPA_VQQGBP4A_I_3LVlbwWkvoiUmNBQYDf55Oh6onp0aDDRxViCCHcclICGGjUhh1j6fnQMmJZwOpVv7GEOKnpB1g"
);
myHeaders.append("Accept", "application/json;odata=verbose");
var requestOptions = {
method: "GET",
headers: myHeaders,
redirect: "follow",
};
fetch(
"https://cooponline.sharepoint.com/sites/TestDemoFeb/_api/web/lists/getbytitle('TestPost')/GetItembyID(4)",
requestOptions
)
.then((response) => response.text())
.then((data) => console.log(data))
.catch((error) => console.log("error", error));
return <div></div>;
}
}
export default FetchRandom;
Could anyone please help me with it?
you can use the concept of states to achieve this in an easy way.
just create a stete like this:
const [data, setData] = useState();
// ///////////////////////////////////////
// in your fetch you can write something like this:
fech("your URL")
.then(res => res.json())
.then(data => {
setData(data);
})
.catch(error => {
setData("An Error Happened: ", error);
})
// /////////////////////////////////////////
then in your returned component, use it by adding curly braces and your state - here is data for example - and you're done!
also you can use some better and elegant thing like conditioanl rendering and so on for better showing.

How do I acquire the data in a json response from a POST request in Next/React?

I am using Next.js api route to handle a POST request then send a response back to the frontend. I have used Rapid API client extension to confirm there is a response being sent to the frontend. I just dont know how to handle it in the frontend.
Here is the code on the api route:
import clientPromise from "../../../config/mongodb";
export default async function userDetailsHandler(req, res) {
const body = req.body;
if (req.method == "POST") {
const client = await clientPromise;
const db = client.db("mood-board");
let emailQuery = await db
.collection("users")
.find({ email: body.email })
.limit(1)
.toArray();
let parsedData = JSON.parse(JSON.stringify(emailQuery));
res.status(200).json(parsedData)
console.log(parsedData)
} else if(req.method = "GET") {
}
}
In the following example, you use the fetch api to post the data which returns a promise. You can use then() which takes a callback function that you can use to operate on the data once that promise is returned.
Example:
useEffect(() => {
// POST request using fetch inside useEffect React hook
const requestOptions = {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ title: 'React Hooks POST Request Example' })
};
fetch('https://reqres.in/api/posts', requestOptions)
.then(response => response.json())
.then(data => setPostId(data.id));
// empty dependency array means this effect will only run once (like componentDidMount in classes)
}, []);

Reading token from AsyncStorage before a fetch call

In my ReactNative app, I'm trying to come up with a nice pattern to read the access_token I store in AsyncStorage and use it in a fetch call.
In other words, I want to create a pattern that uses some type of wrapper that makes sure that the fetch call always has the access_token it needs. So execution order should always be:
Invoke Fetch Call -> Get Token from AsyncStorage and Prep Header -> Execute Fetch Call
I came up with the following code but it looks like I'm having problems with the Async part of AsyncStorage and my fetch calls are going out without the token.
Here's my fetch call:
export const someApiCall = (request) => {
const url = 'https://myapi.com/add';
return (dispatch) => fetch(url, fetchOptionsPost(request))
.then((response) => {
if (response.ok && response.status === 200) {
// Got data. Dispatch some action
}
})
}
Here, I'm using a helper function to prepare the headers, etc. Here's what the fetchOptionsPost() looks like:
export const fetchOptionsPost = (request) => {
getAccessToken()
.then(token => {
return {
method: 'POST',
mode: 'cors',
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer " + token
},
body: JSON.stringify(request)
}
});
};
And the getAccessToken() function simply reads it from AsyncStorage as below:
export const getAccessToken = async () => {
return await AsyncStorage.getItem("access_token");
}
This pattern is NOT working and API calls are going out without a token.
I also want to mention that if I hard-code the token inside my fetchOptionsPost() method, everything works fine. Clearly, the issue here is that the fetchOptionsPost() is not returning anything.
What can I do to make sure that I will ALWAYS have my token in my fetchOptionsPost?
you could add token call inside someApiCall function .And also create the options on inside the function . function was async so fetch only run after get token result
Updated
const fetchOptionsPost = (token) =>{
return ({
method: 'POST',
mode: 'cors',
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer " + token
}
})
}
export const someApiCall = async(request) => {
const token = await AsyncStorage.getItem("access_token");
const url = 'https://myapi.com/add';
fetch(url, fetchOptionsPost(token))
.then(response=>response.json())
.then((data)=>{
// call the dispatch here
})
}
Why use async inside on main function
AsyncStorage only have async callback. if you are set the AsyncStorage as separate function you should call async for the both function.Thats why i added with in parent async function and pass the token to fetchOptionsPost
Here's what I've come up with which seems to work fine. I still would appreciate any suggestions or improvements to this code.
First, here's what my fetch call looks like now. I wrapped it inside the getAccessToken() function which is an async call but because I'm using redux-thunk, I'm able to do this.
export const someApiCall = (request) => {
const url = 'https://myapi.com/add';
return (dispatch) => getAccessToken()
.then(token => {
fetch(url, fetchOptionsPost(request, token))
.then((response) => {
if (response.ok && response.status === 200) {
// Got data. Dispatch some action
}
})
})
}
I slightly changed my fetchOptionsPost() helper function which now accepts the token. It's also a bit more robust now. If it doesn't get a token, it simply omits the Authorization part in the header. I opted for this approach as some calls to my API backend do not require authentication. Also the isValidString() is another helper validation function I created to make sure I do get a valid string. It returns a TRUE or FALSE response based on the string value inputed:
export const fetchOptionsPost = (data, token = null) => {
if (isValidString(token)) {
return {
method: 'POST',
mode: 'cors',
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer " + token
},
body: JSON.stringify(data)
}
} else {
return {
method: 'POST',
mode: 'cors',
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(data)
}
}
};
And finally, the getAccessToken() function which didn't really change but here it is:
export const getAccessToken = async () => {
return await AsyncStorage.getItem("access_token");
}
As I said, I'd appreciate any comments or suggestions on further improving this code.
Hope this is useful to others.
Use Async and await method and get the token before each call.
async ()=>{
let token =await getTokenFromLocal();
return (dispatch) => fetch(url, fetchOptionsPost(request))
.then((response) => {
if (response.ok && response.status === 200) {
// Got data. Dispatch some action
}
})
}

Download file using redux flow

Could not find any example describing it.
I'm trying to create download button using react app but going through redux, ie. in action I'm connecting to url and getting the file in response (code 200).
export function sendTimeline(token, timelineObj) {
const request = axios.post(`muURLGoesHere`, timelineObj, {
headers: {
"Content-Type": "application/vnd.ms-excel",
"X-Accept-Version": "v1",
Authorization: `Bearer ${token}`
}
});
console.log(request);
return {
type: constants.actionTypes.TIMELINE_DATA,
payload: request
};
}
How can I pass it to reducer and download it on the react side.
You maybe know the article with an example or any hint on that.
Thank you
I wouldn't dispatch actions with promised as payload. Use redux-thunk additionally to do more fine grained dispatch of successive actions:
const sendTimeline = (token, timline) => dispatch => {
dispatch({ type: 'sendtimeline/start' })
return fetch(…)
.then(res => res.json())
.then(json => dispatch({
type: 'sendtimeline/success',
payload: json
}))
.catch(err => dispatch({
type: 'sendtimeline/error',
payload: err,
error: true
}))
}
That way you do not have to deal with async problems in the reducer, since the actions handle that. Also you can do stuff like:
this.props.sendTimeline(…).then(…)
when used within a component, since the promise is returned from the action creator.
Have a look here as well

Redux thunk. reading data from local

I would like to read the data from customData.json, through the code below but here it requires a url, although i would like to read it locally instead, is it possible to do this?
var customData = require('./customData.json');
export function fetchQuestions() {
return dispatch => {
fetch(customData, {
method: 'get',
headers: {
'Accept': 'application/json',
"Content-type": "application/x-www-form-urlencoded; charset=UTF-8"
}
})
.then(payload => payload.json())
.then(payload => payload.results)
.then(payload =>
dispatch({
type: 'FETCH_QUESTIONS',
payload: payload
})
)
}
}
If you want to read a JSON from localStorage instead of making a network request every time, it's pretty simple, there's nothing async involved. Assuming you've put it into localStorage.customData:
export function fetchQuestions() {
return dispatch => {
const payload = JSON.parse(localStorage.customData);
dispatch({
type: 'FETCH_QUESTIONS',
payload: payload.results,
});
}
}
Though, unless you're doing something else with it, it would be nicer to save the .results property only onto the disk, rather than the whole payload, since you're not using the rest of it.

Categories

Resources