Axios not retuning correct data - javascript

I have a React application, where I am fetching some data, from an endpoint, where I am expecting two different arrays as response.
When i go into the terminal, i see that, it says Array(2), but when i open up the data tab it only displays one array.
This anybody know if this is a bug or if this is something wrong with my application.
I tried from two separate clients (postman and regular browser), where there was no issue at all, so I am a bit confused, to as why this is happening?
I have taken into account, that the requests are async.
Here is my full code.
const [{data, loading, error}, refetch] = useAxios(fetchInvoiceData);
useEffect(() =>{
if(!loading){
const ids = data.encodedImage.map(entry => entry._id)
console.log(ids)
console.log(fetchMultipleLabelData(ids))
setLoadingPages(true)
axios.get(fetchMultipleLabelData(ids)).then(res =>{
console.log(res)
setLoadingPages(false)
const categories = generateCategories(res.data);
const initialState = generateInitialState(res.data);
setCategories(categories)
console.log(categories)
setGlobalState(initialState)
}).catch(err =>{
console.error(err)
})
}
}, [loading])
I have tried making it conditional by using a loading state to 'wait' with doing the http request.
Furthermore, since it gives a response, i assume, that it would return the full data???
EDIT:
i have no tried Stringifying the json, and logging out the regular output aswell with the following result
console.log(JSON.stringify(res.data))
console.log(res.data)

Related

How to write requests and fetch

I need help how to correctly write a GET and POST request in my server (index.js) and how to properly write the fetch in App.js.
I have read threads here on Stackoverflow and I have searched for information on how to write requests and fetches but I find it very difficult how to add the examples to my own code. I have tried different solutions for three weeks but getting nowhere it feels like. So, please help. I feel like this should not be that difficult, but for some reason it is. I have no one to ask for help other than here.
I'm using the URL http://localhost:8080/reviews
Is this how I write or do I have to add anything? (in Index.js)
app.get("/reviews", (request, response) => {
response.status(201).json
});
app.post('/reviews', async (request, response) => {
response.status(201).json
});
In App.js I want to create a fetch where I GET all the existing reviews that are written (none at the moment since the page isn't done yet) and I want to be able to POST new reviews. When I post a new review I want the page to load and update with the new and all the other written reviews.
I have something like this at the moment, but I don't know what the last parts should be?
const reviewsURL = "http://localhost:8080/reviews"
export const App = () => {
const [existingReviews, setExistingReviews] = useState([])
const [newReview, setNewReview] = useState('')
const fetchReviews = () => {
fetch(reviewsURL, {'
// WHAT ELSE TO WRITE HERE ???
useEffect(() => {
fetchReviews();
}, []);
const postReview = (event) => {
event.preventDefault();
fetch(reviewsURL, {
method: 'POST',
// WHAT DO I WRITE HERE ???
}
return (
<>
<NewReview
newReview={newReview}
setNewReview={setNewReview}
handlesubmit={postReview}
/>
{<AllReviews
allReviews={existingReviews}
/>}
</>
)
}
In express.js, response.status(201).json is not the way to return a JSON response. .json is a function, so you would pass it a JSON-ifiable object, response.status(201).json(resultsArray); or something like that.
A lot of people prefer to use a library for making requests, rather than using fetch. Axios is a common favourite, and lots of people find it much easier to use.
If you'd prefer to use fetch over an easier library, that's fine, fetch is still simple enough to get going with. Here's some documentation on how to use fetch
Of note: the fetch(url) function returns a promise, so you'll either .then the returned promise, or await it inside an async function. If you're expecting a JSON response, the patterns in the example code in the docs require an extra step to get the content:
const result = await fetch(url);
const data = await result.json();
That's for a GET request, but the docs also show how to get going with POST requests.

Cannot set headers after they are sent to the client. Cannot find where the other response is being sent. Maybe componentDidMount method

I have gone through many responses on this topic but none seem to solve my issue. I have an API using NodeJS, ExpressJS and Mongoose. I also have a frontend component that is built using ReactJS. I get the above error on the second or more try when saving data from a form. Note: the error does not show up on the first attempt at saving the form.
The backend code for saving the request to the database is
candidate.save()
.then(result => {
res.status(200).send({
candidate: result,
message: result.name + " has been added successfully"
});
}).catch(err => {
res.status(500).send({ message: err.message || "An error occurred while creating the candidate" });
});
The code that takes the data from the form and makes the request is
CandidateDataService.create(candidate).then(response => {
this.setState({
name: response.data.name,
dob: response.data.dob,
gender: response.data.gender,
party: response.data.party,
district: response.data.district,
comments: response.data.comments,
submitted: response.data.message
});
}).catch(e => { console.log(e) });
The create method in CandidateDataService is
create(candidate) {
return http.post("/candidates", candidate);
}
I have tried using return res.status(200) as stated in answers to similar questions but that didn't work.
I should mention that I have similar code in other controllers for forms that store data and I don't get this error on the NodeJS side. So I don't understand why it works for the others with the exact same code style but not this one. On the ReactJS side there is a difference though. The difference is that this component has the ComponentDidMount method and the others don't. In the ComponentDidMount method I'm fetching all the data from two separate Models to fill the select list.
componentDidMount() {
this.retrieveDistricts();
this.retrieveParties();
}
retrieveDistricts() {
DistrictDataService.getAll()
.then(response => {
this.setState({
districts: response.data
});
}).catch(e => { console.log(e) });
}
retrieveParties() {
PartyDataService.getAll()
.then(response => {
this.setState({
parties: response.data
});
}).catch(e => { console.log(e) });
}
I tried it this way in the componentDidMount method but still the same result
componentDidMount() {
PartyDataService.getAll()
.then(response => {
this.setState({parties: response.data});
DistrictDataService.getAll()
.then(districts => {
this.setState({districts: districts.data});
});
}).catch(error => console.log(error));
}
Since this is the only thing different between this form and the others I believe that's what causing the error, but I don't understand why or how to fix it.
Summary
No issues when using postman to create entries.
The error does not appear the first time the form is save via the frontend. In rare occassions it did not appear on the second attempt either but it always appear on the third attempt.
BackEnd and FrontEnd code works perfect for other forms, that does not need to be prefilled.
Can it be the methods inside componentDidMount? If so, why?
Thank you
After trying multiple tweaks based on hints I received on similar post nothing worked. Playing with the react plugin for firefox, I noticed that the state of the inputs would change to undefined. I realize that there was an error in the variable I used to pass the data to the react state. So this caused the undefined I was getting.
Then in the console tab I noticed an error that said something with respect to uncontrolled and controlled inputs. Apparently my inputs were controlled but then became uncontrolled when I passed the response data to the set the state. This was not necessary.
After I stopped passing the response data to set the state, the error described above stopped appearing. I don't understand why or the theory behind it, but it did the trick.
Hopefully this helps someone else.

Data part of Response is a long script instead of desired json object

I am building a web app using laravel and vuejs. I have made a axios get request to get a list of users .
I am getting a Promise object, and from what i have read. Reason for getting a promise object is because it's an async request.
I have tried .then() to get data part of the response. But i am getting a huge script instead of desired data.
axios......then(function(response){
console.log(response.data);
})
Initially what i did was
var res = axios.get('/allUsers');
console.log(res)
That time i came to know about promise object and read about.
When i checked network in dev tools, status code is 200 and i can see list of users. So i guess my request is successfully completed.
What should be done to get the list of the users. That list i will be using to update my UI.
Depending on what you're getting back for data there are a few ways to handle this. You may need to convert the data after the you get receive the response.
axios.get('some_url')
.then(res => res.json())
.then(data => {
// do something with the data
}).catch(err) {
conosole.error(err);
}
if you're seeing the data come through properly in the response and you're getting what you need without doing that then just do
axios.get('some url').then(res => {
// do something in here with the data here
})
also make sure you're getting back json if that's what you're looking for. check your response to see if its html or json because they can be handled a bit differently
as an "Edit" you could also handle this with async await so you dont end up in callback hell
async function fetchData() {
try {
const res = await axios.get('some url');
// next step might not be necessary
const data = await res.json();
// do something with the data
console.log(data); // if converting it was necessary
console.log(res); // if not converting
} catch (err) {
console.error(err);
}
}

Running query from inside Cloud Function using request parameters

I am having troubles running queries from Cloud Functions using the request parameters to build the query form HTTP calls. In the past, I have ran queries from cloud functions fine with no error. My problem arises when I try to run the query using parameters gotten from the request.
When I hardcode the location of the document in the function, it works fine but when I try to build a query, it returns status code of 200. I have also logged the the built query and it is logging out the right thing but no data is being returned. It only returns data when the document path is hardcoded. See code below.
Query looks like this
https://us-central1-<project-id>.cloudfunctions.net/getData/CollectionName/DocumentName
export const getData = functions.https.onRequest((request, response) => {
const params = request.url.split("/");
console.log("the params 0 "+params[0]);
console.log("the params 1 "+params[1]);
console.log("the params 2 "+params[2]);
//Build up the document path
const theQuery = "\'"+params[1]+"\/"+params[2]+"\'";
console.log("the query "+theQuery); <-- logs out right result in the form 'Collection/Document'
//Fetch the document
const promise = admin.firestore().doc("\'"+params[1]+"\/"+params[2]+"\'").get() <---- This doesnt work, building the query
//const promise = admin.firestore().doc('collectionName/DocID').get() <---- This hard coded and it works
promise.then(snapshot => {
const data = snapshot.data()
response.send(data)
}).catch(error => {
console.log(error)
response.status(500).send(error);
})
});
I tried using a different approach and giving the datafields a names as seen below
Query looks like this
https://us-central1-<project-id>.cloudfunctions.net/getData?CollectionName=CName&DocumentID=Dname
export const getData = functions.https.onRequest((request, response) => {
const collectName = request.query.CollectionName;
const DocId = request.query.DocumentName;
//Build up the document path
const theQuery = "'"+collectName+"\/"+collectName+"'";
console.log("the query "+theQuery); <---Logs out correct result
//Fetch the document
const promise = admin.firestore().doc(theQuery).get() <-- Building the query does not work
//const promise = admin.firestore().doc('collectionName/DocID').get() <---- This hard coded and it works
promise.then(snapshot => {
const data = snapshot.data()
response.send(data)
}).catch(error => {
console.log(error)
response.status(500).send(error);
})
});
In both cases, when the request is build from the URL, it does not return any data and it does not return any errors. And I am sure the documents I am trying to fetch exsist in the database. Am I missing anything ?
Try request.path. Then you can obtain the path components, e.g. request.path.split("/")[1]
The syntax for request.query is valid when using Express. This is referenced in some of the docs, but not made explicit that Express is required. It's confusing.
To properly handle the dynamic inputs, you may have more luck working with Express and creating routes and handlers. This Firebase page has links to some projects using it.
Walkthough set-up using Express on Firebase.

DynamoDB put returning successfully but not storing data

The situation is that I want to store some information in a DynamoDB database, and then send a notification only if I am sure that this information has been stored successfully. Here's what my code looks like:
const putObj = Bluebird.promisify(docClient.put, { context: docClient })
// ... a promise chain collecting information...
const params = {
TableName: 'my_table',
Item: {
name: itemName
}
}
return putObj(params)
.then((data) => {
if (Ramda.equals(data, {})) {
// ... send notification here
.catch((err) => {
throw err
})
I assume that if there is an error storing the data, this will be caught in the catch block and the notification will not be sent. However, I'm seeing in some cases that notifications are being sent despite the fact that the respective information has not been stored in the database. This only happens infrequently - in almost all cases the code functions as desired.
Any ideas about why/how this could be happening, and what I can do to stop it. DynamoDB doesn't return any useful information into the .then - it is only an empty object in case of success, and I'm already checking this before sending the notification.
Are you using 'eventually consistent' or 'strongly consistent' reads?
When you read data from a DynamoDB table, the response might not
reflect the results of a recently completed write operation. The
response might include some stale data. If you repeat your read
request after a short time, the response should return the latest
data.
http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.ReadConsistency.html
You may need to retry your read, or else change the read consistency value.

Categories

Resources