How to get rid of this - message:{'You are not subscribed to this API.'}.? - reactjs

import React from 'react';
import './App.css';
function App() {
fetch("https://spoonacular-recipe-food-nutrition-v1.p.rapidapi.com/recipes/quickAnswer?q=How%20much%20vitamin%20c%20is%20in%202%20apples%253F", {
"method": "GET",
"headers": {
"x-rapidapi-host": "[host]",
"x-rapidapi-key": "[key]"
}
})
.then(response => {
console.log(response);
})
.catch(err => {
console.log(err);
});
return ( <
div className = "App" >
<
form className = 'searchform' >
<
input className = 'search-bar'
type = "text" / >
<
button className = 'search-bar'
type = 'text' > Submit < /button> < /
form > <
/div >
);
}
export default App;

if you have everything set up correct on RapidAPI I would suggest passing the key without using variables because maybe you are passing undefined. For undefined we get exactly the same error.

You have to select a pricing plan, even if it's the free plan. Go to "Pricing" on the page for the API, and select a plan. This fixed the issue for me.
https://api.rakuten.net/Top-Rated/api/e-mail-check-invalid-or-disposable-domain/discussions/9487/keep-getting-this-response-%22You-are-not-subscribed-to-this-API.%22

Be sure that you actually subscribe tothe api on rapid api hub if you aren't subscribed to the api
you're going to get an error message that notifies you don't have an active subscription and your call will not
be successfulbe sure that you actually subscribe tothe api on rapid api hub if you aren't subscribed to the api
you're going to get an error message that notifies you don't have an active subscription and your call will not
be successful
message: you are not subscribed to this api rapidapi
video example

Make sure you select a plan whether it's a free plan or a premium plan.
https://rapidapi.com/tipsters/api/hotels-com-provider/pricing

If you are subscribed to the free plan and still getting this error "message:{'You are not subscribed to this API.'}"
The problem might be related to the .env location. Try placing it inside root of your folder, rather than src folder.

Maybe the problem is with GET, try this. And let me know, if it works or not.
state = {
url:
"<url>",
header: {
"x-rapidapi-host": "<host>",
"x-rapidapi-key": "<key>"
}
};
componentDidMount() {
axios
.post(this.state.url, this.state.header)
.then(res => {
console.log(res.data);
})
.catch(err => console.log("err" + err));
}

For anyone else encountering this issue: the oversight I made was adding 'Bearer ' in from of the RapidAPI key. It should just be the key, without anything in front of it.

This may be stale, but helpful to someone else:
The first thing you want to do is to avoid placing it within .env.
Ensure it works properly within the code snippet (unsafe method) before placing it within .env (current best practice).
For instance, you should first do this:
const options = {
'X-RapidAPI-Key': 'theVeryLenthyKey',
'X-RapidAPI-Host': 'theAPI.p.rapidapi.com'
}
};
Instead of this:
const options = {
'X-RapidAPI-Key': process.env.THE_VARIABLE_NAME_YOU_USED,
'X-RapidAPI-Host': 'theAPI.p.rapidapi.com'
}
};

I got the same response saying {message: you are not subscribed ... but I was, I made sure. So the problem was that it couldn't read from the .env file.
So I used the manual method of directly putting the key in the code while in the development phase, but when I deployed the project I added it in the environment variables of the hosting service and it was working just fine.

If you are passing your key as variables, make sure you place your .env file in root folder (environment variables)

I have fixed this issue by simple directly passing key, like this
export const exerciseOptions = {
method: "GET",
headers: {
"X-RapidAPI-Host": "exercisedb.p.rapidapi.com",
"X-RapidAPI-Key": "xxxxxxxxxxxxxxxxxx",
},
};
don't pass the key through the .env file

Related

Chrome and Edge hang on React page load for only some users, should I change my useEffect strategy?

My ReactJS project displays a simple page consisting of a header section with project title, version and a few nav links, then a table of about 200 results as the main content of the page.
The initial page loads for everyone and the components appear as expected, but on page load (I believe this is when the useEffect hook kicks in) some users report the page becoming un-responsive and no matter how long it is left, it never finishes. This has been reported in both Chrome and Edge by 5 different users across a site of 200+ users, the majority have no issues despite running the exact same hardware and connection.
On page load, I expect the title, version and table contents (plus a few other variables) to be populated and automatically updated since these are in state, and for most users, this works as expected.
Below is my useEffect()
useEffect(() => {
// Update all initial values
fetchLastUpdated();
fetchVersion();
fetchUsername();
fetchUpcomingFilterOptions();
fetchLongCustomerNames();
fetchConfigs();
fetchUpcomingResults() // This will be displayed as rows
const job = document.getElementById("job")
if ( !!job ) {
job.addEventListener("keyup", function(event) {
if (event.key === "Enter") {
submitForm()
}
});
}
// Find environment for API links: testing/pre-release, testing/QA, flx
const url = window.location.href
if ( url.includes('localhost') ) {
setEnvironment("testing/pre-release")
} else if ( url.includes('testing/pre-release') ) {
setEnvironment("testing/pre-release")
} else if ( url.includes('testing/QA') ) {
setEnvironment("testing/QA")
} else if ( url.includes('flx') ) {
setEnvironment("flx")
}
}, [])
Below an example of an API call from useEffect
const fetchConfigs = () => {
axios({
method: "get",
url: "http://myURL/" + environment + "/WITracker/public/api/myConfigs",
config: { headers: {
'Access-Control-Allow-Origin': '*',
"Content-Type": "multipart/form-data"
}}
})
.then(function (response) {
setConfigs(response.data);
})
.catch(function (response) {
console.log("Failed to fetch configs!");
addNotification("Unable to fetch configs", "Retry in progress...")
})
}
When remote accessing the users with troubles loading the page, I asked that they each try the alternative browser: Chrome -> Edge or Edge -> Chrome and in each case this resolved the issue. I found this strange as I would have expected the same browser to be causing the same behaviour each time across the users.
I would like to make sure that the page reliably loads for all users regardless of their browser preference. I'm at a bit of a loss trying to find out why only some users are getting unresponsive errors so any possible solutions or suggestions of what to try are welcome!
Possible workaround?
I'm not sure that I have set up my useEffect the correct way using best practices. I'm thinking of adding a slight delay to the API calls, since the page loads the components without issue, and once the delay is up, to synchronously make each of the calls, giving the browser more of a chance to process the smaller chunks of work rather than all at once... please can somebody let me know their thoughts on this?
e.g. Something similar to the below theory?
useEffect(async () => {
// Some delay here, with loading screen
wait(1000) //custom function to wait?
// ...then, update all initial values
await fetchLastUpdated();
await fetchVersion();
await fetchUsername();
await fetchUpcomingFilterOptions();
await fetchLongCustomerNames();
await fetchConfigs();
await fetchUpcomingResults()
...
Thanks in advance

Axios/Fetch not using next.config.js rewrite

Looking up several examples online, it appears all one would need to do to redirect requests to the backend is to add rewrites to the next.config.js file, and it should work. However, I must be missing or misunderstanding something as this alone doesn't seem to do the trick. Redirecting seems to work if I type the url in the browser, but calls from axios/fetch continue to try to use a path relative to my client. Here are my snippets:
next.config.js
module.exports = {
async rewrites() {
return [
{
source: '/api',
destination: 'http://localhost:3001',
},
]
},
};
components/MyComponent.js
import React, { useEffect } from "react";
import axios from "axios";
function MyComponent({projectName}) {
...
useEffect(() => {
axios.get("/api/project/" + projectName)
.then((res) => {
console.log(res);
});
return;
}, []);
...
};
export default MyComponent;
To clarify, if I hit http://localhost:8001/api/project/Name_of_Project from the browser, I get properly redirected to my server (hosted on port 3001) and receive data I'd expect. However, when I hit my client (http://localhost:8001/Name_of_Project), axios doesn't redirect and tries http://localhost:8001/api/project/Name_of_Project which obviously fails. I also tried the fetch equivalent instead of axios and get the same result.
Is there another step that I need to take? Does the rewrite not work for axios/fetch? I have also seen mentions of the next-http-proxy-middleware package in my search, but I am not sure if this is something that I need to use in conjunction with the rewrite or not.
I appreciate any insight!
EDIT 1:
After doing some more searching, I ran into this post, and discovered that my issue is because I am using relative pathing in my axios call. If I change it to:
axios.get("http://localhost:3001/api/project/" + projectName)
.then((res) => {
console.log(res);
});
then I get my data properly. I suppose this leads me to my next question: is there a way to use relative path alongside the rewrite in the config? I personally think it's a little ugly to have the hostname and port exposed like that (I eventually plan on hosting this app on a FQDN). So if there's anything that can be done about that, I'd love to know!
EDIT 2: Of course the change in my first edit works because I am hitting my server directly! Which is not the desired effect. I want to use the redirect set in the config to go to my api.
Aha! I WAS misunderstanding something. I assumed that the path in the rewrite would reattached my path params for free. This is not the case. A link to the documentation.
The relevant excerpt:
Wildcard Path Matching
To match a wildcard path you can use * after a parameter, for example /blog/:slug* will match /blog/a/b/c/d/hello-world:
module.exports = {
async rewrites() {
return [
{
source: '/blog/:slug*',
destination: '/news/:slug*', // Matched parameters can be used in the destination
},
]
},
}
So my corrected next.config.js:
module.exports = {
async rewrites() {
return [
{
source: '/api/:slug*',
destination: 'http://localhost:3001/api/:slug*',
},
]
},
};

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

Fetch status 200 but pending endllessly, except first call

I've been searching to solve this problem for a while but couldn't find a working solution.
I'm making a simple social network website and this API returns a article data such as text, image and video url, etc, all saved in server's local MySQL Database. My front-end is React and server is Nginx reverse proxy with Node.js using Express. When I load the page, I create 5 React components that each make fetch request for given article number.
The following code snippet is the fetch API that asks the server to fetch data from database:
//server-side script
app.get('/api/getArticle/:id', (req, res) => {
const con = mysql.createConnection({
host: 'myhost_name',
user: 'myUser',
password: 'myPassword',
database: 'myDB',
});
con.connect(function (err) {
if (err) {
throw err;
}
console.log("Connected!");
})
const idInterest = req.params.id.toString();
console.log(idInterest)
let sql = 'some_sql';
con.query(sql, function (err, result) {
if (err) {
res.status(500).send("Error while getting article data");
return;
}
else {
res.set('Connection', 'close')
res.status(200).send(result);
console.log("ended")
con.end();
return;
}
})
}
//React script
//index.js
fetch('http://mywebsite.com/api/getMaxArticleId/')//Retrieve top 5 article ID
.then((response) => {
for (let i = 0; i < data.length; i++) {
nodesList.push(<Container articleId={data[i]['id']}/>)
}
ReactDOM.render(<React.StrictMode><NavBar />{nodesList}<Writer writer="tempWriter" /></React.StrictMode>, document.getElementById('root'));
})
//Container.jsx; componentDidMount
const url = "http://mywebsite.com/api/getArticle/" + this.props.articleId.toString();
fetch(url, {
method: 'GET',
credentials: "include",
}).then((response) => {
response.json().then((json) => {
console.log(json);
//processing json data
This used to work very fine, but suddenly the getArticle/:id calls started to show 200 status but 'pending' in 'time' column in Chrome network tab, endlessly, all except the first*getArticle/:idcall. This prevents my subsequent .then() in each Container from being called and thus my entire tab is frozen.
Link to image of network tab
As you see from the image, all pending fetches are missing 'Content Download' and stuck in 'Waiting(TTFB)', except the first call, which was '39'
I checked the API is working fine, both on Postman and Chrome, the server sends result from DB query as expected, and first call's Json response is intact. I also see that console.log(response.json()) in React front-end shows Promise{<pending>} with *[[PromiseStatus]]: "Resolved"* and *[[PromiseValue]]* of Array(1) which has expected json data inside.
See Image
This became problematic after I added YouTube upload functionality with Google Cloud Platform API into my server-side script, so that looks little suspicious, but I have no certain clue. I'm also guessing maybe this could be problem of my React code, probably index.js, but I have no idea which specific part got me so wrong.
I've been working on this for a few days, and maybe I need common intelligence to solve this (or I made a silly mistake XD). So, any advices are welcomed :)

How to resolve an url by fetch & redirect without refresh with react

I need to fetch the current url in my react application because our front/nginx may respond with a redirect which won't be hit if user has the service-worker active..
therefor I currently have this logic in my 404 component on didMount.
fetch('/test/page/xxxx/', {redirect: 'follow'}).then(res => {
if(res.status === 200 && res.redirected) {
console.log(res)
// this.props.push(res.url)
// window.location.replace(res.url)
// window.location.hash = res.url
console.log('Redirected to ' + res.url)
}
})
the res.url that I get back in the respons is a full url ex: https://example.net/xxx/xxx/xxxx which makes it hard for me to use push from react-router-redux because it expects a relative url. Can anyone help me with a regex that can get the slugs from the res.url or does anyone have any other idea how to solve this problem?
There is the URL interface [1] available in the window that can be used create a URL object.
A URL object has the pathname property that is used to retrieve the path component of the URL.
this.props.push(
new URL(res.url).pathname
)
The easiest way to get the pathname (relative URL) is by parsing it with the URL interface API
const { pathname } = new URL("https://example.net/aaa/bbb/ccc");
console.log(pathname) // "/aaa/bbb/ccc"
In the context of your code
fetch("/test/page/xxxx/", { redirect: "follow" }).then(res => {
if(res.status === 200 && res.redirected) {
const { pathname } = new URL(res.url);
this.props.push(pathname);
}
});
NOTE: Not supported in IE11 and below. If support for that browser is needed, there is a polyfill https://github.com/lifaon74/url-polyfill
There is also a proposal to be added to babel, expected soon to be a stage 0 feature

Resources