How to push response data redux saga - javascript

so the idea is everytime i click the button it will dispatch my action,and i want to push my response data into an array, but it always overwrite an exising array, how do i fix it?
this is my code
function searchApiPhoto(param, page) {
const config = {
headers: {
Authorization: 'api-token',
},
}
return axios
.get(apiurl, config)
.then((res) => {
let data = []
// let result = [];
// console.log("data :", res.data.results);
// data = [...res.data.results];
// data.push(...res.data.results);
data.push(res.data.results)
console.log('datas =>', data)
// return result;
return res.data.results
})
.catch((err) => {
console.log(err)
})
}

Related

React Fetch Inside a function Map

I'm trying to make a request for each item captured in the MAP, but I would like to wait for the response before going to the other object within the MAP. At the moment my code is making all the requests at the same time, which ends up crashing the Backend.
function RequestComputers (Computers) {
Computers.map((e) => {
Details(e, data.region, data.apitoken).then(data => {
if(data)
setContent2((array) => [...array, data[0]])} ).catch(error => console.log(error))
})
}
const Details = async (Computer, region, token) => {
try {
const test = {'region': region, 'apitoken': token, 'product': '1', 'computer': Computer}
const response = await fetch('url', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(test)
}
)
const data = await response.json()
return data
} catch(error) {
console.log(error)
}
}
I need to wait for the fetch response and only then make another fetch request
You can use a simple for loop:
async function RequestComputers (Computers) {
for ( const computer of Computers ) {
try {
const data = await Details(computer, data.region, data.apitoken);
if ( data ) {
setContent2((array) => [...array, data[0]]);
}
} catch(error){
console.log(error);
}
}
}
Reference
I think you could use .forEach and await Details:
async function RequestComputers (Computers) {
Computer.forEach(async(computer) => {
try {
const data = await Details(computer, data.region, data.apitoken);
if ( data ) {
setContent2((array) => [...array, data[0]]);
}
} catch(error){
console.log(error);
}
})
}

Error from catch is not returned in JavaScript

I created the next function that should return the response, data and error in case if exists.
const login = function(cb) {
fetch('https://jsonplaceholder.typicode.com/todos/1')
.then((response) => {
cb(null, null, response);
return response.json();
})
.then((data) => {
cb(data, null, null);
})
.catch((e) => {
console.log('error inside catch:', e.message)
cb(null, null, e)
})
}
console.log(login((data, response, err) => console.log('data', data, 'response', response, 'error', err)))
So, I have to return all these values, but I can return just data. If I change this: https://jsonplaceholder.typicode.com/todos/1 to this: https://j123sonplaceholder.typicode.com/todos/1, to return err, I get undefined. The same issue is with response.
Question: How to get all these values?
// you write
cb(response);
cb(data);
cb(error);
// so the data and error below make no sense
cb(response, data, error)
You passed 3 params to the cb when using it in console.log. But in the login function declaration, cb accepts only 1 param.
That means your console.log always prints 2 times, the first is the Response of API call and the second is the data (if success - then) or error (if fail - catch).
const arr = []
const login = function (cb) {
// const arr = []; move array inside login function if not use outside
fetch("https://jsonplaceholder.typicode.com/todos/1")
.then((response) => {
arr[0] = response;
return response.json();
})
.then((data) => {
arr[1] = data;
})
.catch((e) => {
arr[2] = e;
})
.finally(() => {
cb(...arr);
});
};
login((response, data, err) => console.log('response', response, 'data', data, 'error', err))
// console.log(arr[0]) // response
// console.log(arr[1]) // data
// console.log(arr[2]) // error

Searchbar in react to call table of data

I'm trying to create a searchbar in react that creates a table of data from an API inside the current view.
async function handleSearch() {
console.log("searching...", searchRef.current?.value);
setMessage("Searching...");
var headers = {
"Content-Type": "application/x-www-form-urlencoded",
"auth-token": token,
};
fetch(
"http:"..
{
method: "GET",
headers: headers,
}
)
.then((response) => {
setMessage("");
if (response.status !== 200) {
console.log("erROR", response);
return null;
} else {
console.log("success", response);
this.searched = true;
let productList = response.json()
return productList;
}
})
.then((responseData) => {
console.log("responseData", responseData);
// setting resonseData to productList
setProductList(responseData);
});
}
For some reason this is ridiculously hard to get working.
I would imagine the code above would work and fill the table with the correct array, but is it not.
The JSON response is like this and works properly in the console with the search component currently.
Any idea on how to solve this issue?
It seems you need to add productList as state variable like below.
// We need to initialize with empty array. Otherwise while rendering component for the first time it will try to access map of undefined(productList).
const [productList,setProductList] = useState([]);
// And then in your fetch call you can store data inside productList
fetch(
"http://localhost:5000/adverts/mwap?searchTerm=" +
encodeURIComponent(searchRef.current.value),
{
method: "GET",
headers: headers,
}
)
.then((response) => {
setMessage("");
if (response.status !== 200) {
console.log("erROR", response);
return null;
} else {
console.log("success", response);
this.searched = true;
let productList = response.json()
return productList;
}
})
.then((responseData) => {
console.log("responseData", responseData);
// setting resonseData to productList
setProductList(responseData);
});

return undefined fetch inside AsyncStorage

I have a react-native app where I do a call to an api where it should return the JSON but I'm just having undefined.
export function fetchFromAPI() {
AsyncStorage.getItem('#token', (errToken, token) => {
let token = null;
const requestBody = { token: token };
return fetch(url, {
method: 'POST',
body: JSON.stringify(requestBody)
})
.then((response) => response.json())
.then((responseJSON) => {
console.log(responseJSON); // <-- this shows the correct JSON data
return responseJSON;
}).catch((error) => {
// console.error(error);
});
});
}
I also call that funcion like this:
const apiData = fetchFromAPI();
If I do console.log() inside the fetch function, it returns the JSON data but if I do to apiData, it just gets undefined.
Does anyone has some idea why its like this, I'm doing something wrong?
You can use Promise to get response from fetchFromAPI function, like
export function fetchFromAPI() {
return new Promise((resolve, reject) => {
AsyncStorage.getItem('#token', (errToken, token) => {
let token = null;
const requestBody = {
token: token
};
return fetch(url, {
method: 'POST',
body: JSON.stringify(requestBody)
})
.then((response) => response.json())
.then((responseJSON) => {
console.log(responseJSON); // <-- this shows the correct JSON data
resolve(responseJSON);
}).catch((error) => {
reject(error);
});
});
});
}
When calling the fetchFromAPI, use await, like
const apiData = await fetchFromAPI();
You can also use .then to capture the response and store it in the state, like
fetchFromAPI.then((data) => {
// use data here
});
Hope this will help!
First, you need to return the Promise created by getItem:
export function fetchFromAPI() {
return AsyncStorage.getItem('#token', (errToken, token) => {
let token = null;
const requestBody = { token: token };
return fetch(url, {
method: 'POST',
body: JSON.stringify(requestBody)
})
.then((response) => response.json())
.then((responseJSON) => {
console.log(responseJSON); // <-- this shows the correct JSON data
return Promise.resolve(responseJSON); // <-- this wraps the JSON into a Promise
}).catch((error) => {
// console.error(error);
});
});
}
Then you need to call the function like this:
fetchFromAPI().then(apiData => {...

localstorage.getitem('key') sometimes returns null - in a react app

this is a very weird problem! I'm trying to build a login form which sets a JWT token in localstorage. Other forms then use that token to post requests. I can see the token in my console.log just fine, but sometimes (like 3 out of 5 times), when I am setting localstorage.getitem('idToken'), it shows as null. This behavior most noticeably happens when I remove the console.log(idToken) from my loginUser() function (code in actions.js file - given below). What am I doing wrong? my app is built using React/Redux.
action.js
export function loginUser(creds) {
const data = querystring.stringify({_username: creds.username, _password: creds.password});
let config = {
method: 'POST',
headers: { 'Content-Type':'application/x-www-form-urlencoded' },
body: data
};
return dispatch => {
// We dispatch requestLogin to kickoff the call to the API
dispatch(requestLogin(creds));
return fetch(BASE_URL+'login_check', config)
.then(response =>
response.json().then(user => ({ user, response }))
).then(({ user, response }) => {
if (!response.ok) {
// If there was a problem, we want to
// dispatch the error condition
dispatch(loginError(user.message));
return Promise.reject(user)
} else {
localStorage.setItem('idToken', user.token);
let token = localStorage.getItem('idToken')
console.log(token);
// if I remove this log, my token is returned as null during post.
dispatch(receiveLogin(user));
}
}).catch(err => console.log("Error: ", err))
}
}
here's my POST request:
import axios from 'axios';
import {BASE_URL} from './middleware/api';
import {reset} from 'redux-form';
let token = localStorage.getItem('idToken');
const AuthStr = 'Bearer '.concat(token);
let headers ={
headers: { 'Content-Type':'application/json','Authorization' : AuthStr }
};
export default (async function showResults(values, dispatch) {
console.log(AuthStr);
axios.post(BASE_URL + 'human/new', values, headers)
.then(function (response) {
console.log(response);
alert("Your submit was successful");
//dispatch(reset('wizard'));
}).catch(function (error) {
console.log(error.response);
alert(error.response.statusText);
});
});
This GET request works everytime, BTW:
getHouses = (e) => {
let token = localStorage.getItem('idToken') || null;
const AuthStr = 'Bearer '.concat(token);
axios.get(BASE_URL + 'household/list', { headers: { Authorization: AuthStr } }).then((response) =>
{
let myData = response.data;
let list = [];
let key =[];
for (let i = 0; i < myData._embedded.length; i++) {
let embedded = myData._embedded[i];
list.push(embedded.friendlyName);
key.push(embedded.id);
}
this.setState({data: list, key: key});
})
.catch((error) => {
console.log('error' + error);
});
}
I'm at my wit's end! Please help!
The localStorage.setItem() is a asynchronous task, and sometimes you run let token = localStorage.getItem('idToken') just after the setItem will fail, so you get a null, so please put the getItem operation some later, have a try, it will be different :
setTimeout(function() {
let token = localStorage.getItem('idToken');
dispatch(receiveLogin(user));
}, 50);
Move your token logic (i.e. localStorage.getItem('idToken');) inside the exported function and it should work
export default (async function showResults(values, dispatch) {
let token = localStorage.getItem('idToken');
const AuthStr = 'Bearer '.concat(token);
let headers ={
headers: { 'Content-Type':'application/json','Authorization' : AuthStr
}
};
axios.post(BASE_URL + 'human/new', values, headers)...
There can't be a case where you set a key value in localstorage and then it returns you null, immediately in the next line.
localStorage.setItem('idToken', user.token);
let token = localStorage.getItem('idToken');
This will only happen if your user.token value is null.
Maybe the case here is your thennable function not returning value to your next then like this:
....
.then(response =>
// return response to your next then function
// this will be passed to next then function as params
return response.json();
).then(({ user, response }) => {
....
Make a function whose return the value or a default value
const [hideTyC, setHideTyC] = useState(false);
const loadTyCFlag = (): any => {
if (
localStorage.getItem("tyc") !== null ||
localStorage.getItem("tyc") !== undefined
) {
return localStorage.getItem("tyc") || false;
}
};
useIonViewDidEnter(() => {
hideTabBar();
setHideTyC(loadTyCFlag());
});

Categories

Resources