How to write requests and fetch - javascript

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.

Related

Fetch hook based on router params doesn't work on page refresh

I fetch property data through params. In this property data are ID's of agents located. So, after successfully fetching the property data, I want to fetch the agents data through the just received ID's. The problem, if I manually refresh the page, the agent data isn't fetching. If I enter the page through the app navigation, it will.
Why is that? Or do I have to change something in the structure of how I fetch the data?
async fetch() {
try {
const property = await this.$axios.$get(
`/api/get-specific-property/${this.$route.params.id}`
)
if (property.success) {
this.property = property.data
const agentIDs = property.data.agents
this.getAgents(agentIDs)
}
} catch (err) {
console.log(err)
}
},
methods: {
async getAgents(agentIDs) {
try {
const agents = await this.$axios.$post('/api/get-specific-agents', agentIDs)
if(agents.success) {
this.agents = agents.data
}
} catch(err) {
console.log(err)
}
}
}
You should probably await your method with the following
await this.getAgents(agentIDs)
The rest looks fine!
Using SSR fetch() is run by default on serverSide
if You specify fetchOnServer: false then it's only happening on clientSide
#PhilippeUn it could be cleaner to use async/await syntax instead of try/catch. But for sure easier to resolve the both of APIs call in fetch hook. (Then always You can use this.$fetch() and it'll re-run the hook.)
it allows to use the $fetchState.error/pending state
Just a hint to stop using console.log for error, try to use console.error as it makes trace of the errors.
But my main concern is that there's used $POST method to GET data? Use GET for requesting data
I understand that by POST You can use BODY in the request but it makes a lot of risks for the backend.

How do I make my React file sleep for 5 seconds before continuing?

So I want to make my function delay reading lines before navigating to another page. I have a microservice currently running on an infinite loop which reads and writes from a text file. Since the process can take a while, I would like to wait at least 5 seconds. Here's my code:
import { Link } from 'react-router-dom';
import { useNavigate } from 'react-router-dom';
import React from "react";
import axios from "axios";
import raw from '../command_file.txt';
function HomePage() {
let navigate = useNavigate();
let result;
const [ingredientInput, setIngredientInput] = React.useState();
const handleSubmit = async (e) => {
e.preventDefault();
const data = {ingredientInput};
console.log(data.ingredientInput);
console.log(JSON.stringify(data));
const response = await fetch('http://localhost:5000/verify', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify(data),
});
if (response.status === 201){
console.log("Connected to microservice!");
} else {
console.log(`Error, status code = ${response.status}`)
}
console.log(JSON.stringify(response.json));
fetch(raw)
.then(r => r.text())
.then(text => {
console.log('text decoded:', text);
console.log(text[7]);
result = text[7];
navigate("/result", result);
});
};
I want to be pause the program before fetch is called by 5 to 10 seconds so result can be populated by a variable in which the file can later pass on the result using navigate. Unfortunately, I haven't been able to get anything like setTimeout working. As the program runs now, result ends up being passed as undefined and the variable text returns old data from the text file. I am out of ideas, would anyone be able to point me in the right direction as to what I need to do?
I am not quite sure if this would help in your case, but you can use this cool manual js sleep function:
const sleep = ms => new Promise(r => setTimeout(r, ms));
and then before the fetch, you can call it like:
await sleep(5000)
I'm not sure I understand what you're building here, but it seems like you're using that public .txt file as a database, which is really not a good idea. Ideally you want your microservice to write to the database and return whatever your frontend code needs directly.
In your case the flow could look like this:
You send the ingredients list to the microservice
The microservice does all the necessary calculations and inserts the data into a database (e.g. SQLite or PostgreSQL)
The microservice then returns the redirect URL directly
You code would then look something like this:
fetch('http://localhost:5000/verify', { ...postHeaders }).then(
res => res.json()).then(res => navigate(res["url"]))
Edit: If you really must do it this way, I'd look at the way you're importing the txt file. You need to make sure it's in a public directory (e.g. can be served by nginx) and that you actually fetch it from that public URL as opposed to importing it at build time. However, I'm still not sure why they make you do it this way as it really doesn't make much sense.

Handling non JSON API in Javascript

So I am trying to get a circulating supply number of a token and use the API to do a further calculation with it.
All I could find was people handling JSON outputs but this is just a plain output:
https://avascan.info/api/v1/supply?q=circulatingSupply
Anyone that can help me how I can fetch this amount and use it to further do calculations with?
You can use the fetch API, which have a text method on it's response, for example:
const BASE_URL = 'https://avascan.info/api/v1/supply?q=circulatingSupply';
async function getCirculatingSupply() {
const response = await fetch(BASE_URL);
const data = await response.text();
return Number(data);
}
getCirculatingSupply().then(console.log);
Keep in mind that maybe you will have problems with CORS, as I had testing this API, so maybe you will need to use a proxy server like cors-anywhere to bypass this problem.

Get a particular URL in Node JS other ways

I have a REST API of Reddit. I am trying to parse the JSON output to get the URL of the responses. When I try to send the request, I get multiple outputs, but I am not sure how to do it as it's a random response.
https
.get("https://www.reddit.com/r/cute/random.json", resp => {
let data = "";
resp.on("data", chunk => {
data += chunk;
});
const obj = JSON.parse(data);
resp.on("end", () => {
console.log(obj.url);
});
})
.on("error", err => {
console.log("Error: " + err.message);
});
This is the code I have got. I used the default Node's http library and I don't think it worked. I have never used any Node Libraries, so it will be helpful if you can suggest them too. And also let me know if what I have done is right.
I understand that http is a core library of Node JS, but I strongly suggest you to use something like node-fetch. Make sure you run the following command on your terminal (or cmd) where your package.json file exists:
$ npm install node-fetch
This will install the node-fetch library, which acts similarly to how the Web based fetch works.
const fetch = require("node-fetch");
const main = async () => {
const json = await fetch("https://www.reddit.com/r/cute/random.json").then(
res => res.json()
);
console.log(
json
.map(entry => entry.data.children.map(child => child.data.url))
.flat()
.filter(Boolean)
);
};
main();
The URLs that you are looking for, I could find in the data.children[0].data.url so I did a map there. I hope this is something that might help you.
I get multiple output for the same code, run multiple times, because the URL you have used is a Random Article Fetching URL. From their wiki:
/r/random takes you to a random subreddit. You can find a link to /r/random in the header above. Reddit gold members have access to /r/myrandom, which is right next to the random button. Myrandom takes you to any of your subscribed subreddits randomly. /r/randnsfw takes you to a random NSFW (over 18) subreddit.
The output for me is like this:
[ 'https://i.redd.it/pjom447yp8271.jpg' ] // First run
[ 'https://i.redd.it/h9b00p6y4g271.jpg' ] // Second run
[ 'https://v.redd.it/lcejh8z6zp271' ] // Third run
Since it has only one URL, I changed the code to get the first one:
const fetch = require("node-fetch");
const main = async () => {
const json = await fetch("https://www.reddit.com/r/cute/random.json").then(
res => res.json()
);
console.log(
json
.map(entry => entry.data.children.map(child => child.data.url))
.flat()
.filter(Boolean)[0]
);
};
main();
Now it gives me:
'https://i.redd.it/pjom447yp8271.jpg' // First run
'https://i.redd.it/h9b00p6y4g271.jpg' // Second run
'https://v.redd.it/lcejh8z6zp271' // Third run
'https://i.redd.it/b46rf6zben171.jpg' // Fourth run
Preview
I hope this helps you. Feel free to ask me if you need more help. Other alternatives include axios, but I am not sure if this can be used on backend.

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);
}
}

Categories

Resources