Select data from firebase via id gives me a CORS error - reactjs

I'm deleting data from my firebase db with fetch but I can't figure out how to point to an exact ID.
const deleteHandler = async (id) => {
console.log(id);
await fetch(
`https://react-task-tracker-8e519-default-rtdb.firebaseio.com/tasks.json/${id}`,
{
method: "DELETE",
}
);
I tried it this way, but it gives me a CORS error.
I'm also displaying data from this db, that works fine.
UPDATE: I also want to say that when i console.log the id it gives me the correct one.

(Tl;dr: Try adding '.json' to the end of the endpoint.)
I would recommend reading this page to get a general understanding of what a CORS error is and why it might be happening.
In your case, I would recommend using the Firebase SDK that is best suited to your application. You could start here and follow the setup instructions for whichever is most applicable to your use case (perhaps the node client sdk)?
If you must avoid using the sdks for some reason then I would refer to some other Stackoverflow questions such as this one, which suggests that all Firebase REST endpoints need to end with '.json'.

You just need to add .json at the end of your request and remove .json from tasks.json. like this:-
await fetch(
`https://react-task-tracker-8e519-default-rtdb.firebaseio.com/tasks/${id}.json`,

const deleteHandler = async (id) => {
console.log(id);
await fetch(
`https://react-task-tracker-8e519-default-rtdb.firebaseio.com/tasks/${id}.json`,
{
method: "DELETE",
}
);
Just replace .json text with ${id}.json.
Have a nice day

Related

Can URL API endpoint self-correct?

I am using fetch API inside a React application to retrieve and display some quiz questions.
This is my url endpoint: https://opentdb.com/api.php?amount=${amount}&difficulty=${difficulty}&type=multiple
I have noticed that:
-when I misspell part of the URL before "?" then the response doesn't get back.
example:https://opentdb.com/api.ph?amount=${amount}&difficulty=${difficulty}& (missing "p" of php)
-when I misspell part of the url after "?" then, sometimes I get an empty array back, sometimes I get the data back. How can I get data back with a wrong URL?
example: https://opentdb.com/api.php?amoun=${amount}&difficulty=${difficulty}&type=multiple (missing "t" in amount)
I haven't deployed the application yet, I am using vsc and run npm start to develop the application.
Is it possible that the URL auto-corrects? or maybe it gets cached?
my code:
export const fetchQuizQuestions = async (
amount: number,
difficulty: Difficulty
) => {
const endPoint = `https://opentdb.com/api.php?amount=${amount}&difficulty=${difficulty}&type=multiple`;
try {
const response = await fetch(endPoint);
console.log(response);
const data = await response.json();
console.log(data);
if (data.results.length === 0) {
throw new Error("The part after ? contains some mistake");
}
//below I create the new property "all_answers" and make sure the answers order is never the same
return data.results.map((question: Question) => ({
...question,
all_answers: shuffleArray([
...question.incorrect_answers,
question.correct_answer,
]),
}));
} catch (error: any) {
console.log(error.name);
console.log(error.message);
}
};
Before the ? It's the url. So if you make a mistake there, basically it's like sending a letter to a different adress, so you will not get any answers.
After the ? it's the query string. So you're asking for a result, with some parameters (your query)
So if you're saying like "ok, send me back answers with amount = XXX" but you misspell amount, it's just like "ok send me back answers" because you're not asking for amount anymore (but amoun which is nothing for the endpoint)

Issues with req.query, req.params, req.body using express+axios in MERN app

I am trying to make the following call in React using axios:
axios.get(`http://localhost:5000/daily_batches/num_tweets_by_tag_and_date/`, {
params: {
tag: "Green/Sustainable Energy",
date: "2021-05-07"
}
})
.then(res => {
console.log(res)
})
Should I use req.params, req.body or req.query in my express route for the axios call to be successful? If I use req.params, like so:
router.route('/num_tweets_by_tag_and_date/').get(async (req, res) => {
try {
const tag = req.params.tag;
const date = req.params.date;
const tag_num_tweets_field = "tags." + tag + ".num_tweets"
const num_tweets_data = await DailyBatch.findOne({"date": date}, {[tag_num_tweets_field]: 1, "_id": 0});
res.json(num_tweets_data)
} catch (err) {
console.log(err)
res.status(400).json({
errors: {
global: "An error occurred."
}
})
}
});
I get a "data:null" as shown in this screenshot. And indeed by doing console.log(req.params.tag) and console.log(req.params.date) in the route I get "undefined"
If I use req.body.tag and req.body.date instead of req.params.tag and req.params.date, I still get "undefined" when I console.log(date) and console.log(tag). And the api response is still "data:null". However, in Insomnia the api call works just fine and returns the expected data, as shown in the pic below:
If I use req.query.date and req.query.tag, I successfully get the data in the axios api call I make in React. However, the call does not work in Insomnia, where I get "null".
I cannot seem to find a way to make the get call in React using axios and passing a dictionary with the call parameters, while at the same time being able to make calls to the same endpoint in Insomnia. The only way I found is to use req.param("tag") and req.param("date") but apparently it's deprecated and so I would not want to use that.
I have read multiple posts about req.params, req.body and req.query but the more I read about this the more I am getting confused. Any help would be appreciated!
Probably req.body.
req.params is used if you set up your route using variables, such as
router.get('/users/:id', (req, res)=>{})
you can console.log(req.body) to check.
req.params is used when you have dynamic route .
Example= /:num_tweets_by_tag_and_delete
check here: Node.js: req.params vs req.body

Async Clipboard API "ClipboardItem is not defined" - Reactjs copy image to Clipboard

I'm working on React js, I created my app with create-react-app using npm. I was trying to build a button that takes an image and writes it to the clipboard. Fourtunately I found this npm library that seems to work fine! But keeps me thinking why I couldn't use the ¿built-in? Asynchronous Clipboard API to copy the image (the text copy works fine). I read a really enlightening guide here, and kept reading other great guide here, so I tried all the codes suggested, there and in other pages (despite they don't seem to really change the functionality, I got to try). I came with the same error in every try that impedes to compile: "'ClipboardItem' is not defined no-undef". One code for example was this one:
const response = await fetch('valid img url of a png image');
const blob = await response.blob();
await navigator.clipboard.write([new ClipboardItem({ 'image/png': blob})]);
It seems to be simple, easy to follow. The problem is when you need to put the data in a form the Clipboard can read it, make it a blob, because I need the ClipboardItem constructor, and my app seems to be unable to recognize it as such. Keeps returning ClipboardItem is not defined or, if I somehow define it, says it's not a constructor, of course. I tried with other constructors like Blob(), but had the same problem. The last thing kept me thinking that, since I'm new in the programming world, if there is something kinda basic I don't know of the interaction of Web Apis like this one with node or Reactjs, and if there is a solution, of course! Thanks in advance, you guys are great!
Edit: adding the whole component code as requested:
import React from "react";
function TestingClipAPI () {
async function handleScreenshot () {
const response = await fetch('https://i.postimg.cc/d0hR8HfP/telefono.png');
const blob = await response.blob();
await navigator.clipboard.write([new ClipboardItem({ 'image/png': blob})]);
};
return (
<div>
<button onClick={handleScreenshot} id="buttonID">test</button>
</div>
)
};
export default TestingClipAPI;
Possible issue: This might be because of CRA (Create-React-App) config - similar issue. Something like the library linked can be done, create a canvas and copy the image from there.
Solution or a way to make it work anyway: make a call this way before using ClipboardItem:
const { ClipboardItem } = window;
Note: this also works with other constructors like toBlob and HTMLCanvasElement that had the same issue.
Things to look for:
Browser support Clipboard
Secure origin on HTTPS or localhost. See this post.
How the function is being called - in the OP's case - onClick & asynchronous.
The issue is that onClick are not asynchronous by default and you are not awaiting the response and you also have a typo in navigator.clipboard.
const handleScreenshot = async () => {
try {
const response = await fetch(
"https://i.postimg.cc/d0hR8HfP/telefono.png"
);
const blob = await response.blob();
await navigator.clipboard.write([
new ClipboardItem({ "image/png": blob }),
]);
} catch (err) {
console.error(err);
}
}
return (
<button onClick={async () => await handleScreenshot()} id="buttonID">
test
</button>
);
There are tradeoff between inline function and below are alternatives. I'd personally use the latter method.
function handleScreenshot() {
async function screenShot() {
try {
const response = await fetch(
"https://i.postimg.cc/d0hR8HfP/telefono.png"
);
const blob = await response.blob();
await navigator.clipboard.write([
new ClipboardItem({ "image/png": blob }),
]);
} catch (err) {
console.error(err);
}
}
screenShot();
}
return (
<button onClick={handleScreenshot} id="buttonID">
test
</button>
);
Lastly, you can return a chained promise.
Simply add window in front of ClipboardItem like the following
window.ClipboardItem(...)
Unfortunately, as of the time of this answer, ClipboardItem isn't supported in Firefox. (Support can be enabled via an about:config setting; but of course, most Internet users will not have done this.)
Source: https://developer.mozilla.org/en-US/docs/Web/API/ClipboardItem#browser_compatibility

Localhost being prepended to Fetch request

I'm using a https url and for whatever reason fetch is adding localhost:300 to the start of the url. When I check the url that it's calling I get this: http://localhost:3000/%E2%80%8Bhttps://www... anybody know why?
// load API
componentDidMount() {
fetch('https://www.URL.com/api/route').then(res => {
return res.json()
}).then(data => {
this.setState({
orders : data
})
})
}
I encountered the same problem, and it was because I had a whitespace character in the beginning of the url before "https...". Perhaps you had a similar problem so fetch read the url as a relative path instead.
I had a similar problem in react application I was building. Mistyped URL was my mistake.

admin-on-rest Using PATCH method

I am a junior node developer and am trying out admin on rest to quickly run up an admin panel for my json api. However, all of my update requests use patch instead of put. I attempted revising the UPDATE method in my restClient but this seems wrong (the rest of the methods are removed for brevity)
export default (apiUrl, httpClient = fetchJson) => {
const convertRESTRequestToHTTP = (type, resource, params) => {
let url = ''
const options = {}
switch (type) {
case UPDATE:
url = `${apiUrl}/${resource}/${params.id}`
options.method = 'PATCH'
options.body = JSON.stringify(params.data)
break
return { url, options }
}
}
To me this makes sense but when I try to edit an object I get back HTTP/1.1 404 Not Found <pre>Cannot PUT </pre>
I know that that this wasn't possible with previous versions but I read this https://marmelab.com/blog/2017/03/10/admin-on-rest-0-9.html#http-patch but was a little confused on how it works? I guess I just don't know where to start with this.
if problem still is actual now, please check some places which are using by me to set my customRestClient.
// App.js
import customRestClient from './customRestClient';
in my case i'm using httpClient to add custom headers:
import httpClient from './httpClient';
below:
const restClient = customRestClient('my_api_url', httpClient);
and finally:
<Admin title="Admin Panel" restClient={restClient}>

Resources