How do I correctly call an HTTP API GET request to weatherstack? - reactjs

I'm trying to do a GET request to api.weatherstack.com (see documentation).
Here's my react effect hook:
useEffect(() => {
if (country === undefined) return
console.log(country.name)
axios
.get('http://api.weatherstack.com/current', {
params: {
access_key: api_key,
query: country.name
}
})
.then(response => {
console.log(response.data)
setWeather(response.data)
})
}, [api_key, country])
However, every single time I run this, I get this error:
{ code: 105, type: "https_access_restricted", info: "Access Restricted - Your current Subscription Plan does not support HTTPS Encryption." }
Doing the API call through my browser or through Postman works perfectly, so I'm thinking that there's probably an issue with how I'm using React or Axios.
Also, this API call works about 10% of the time, so I'm confused about why that might happen too.

I think it's because you are using the free plan
weatherstack.com https encryption

Try:
.get("http://api.weatherstack.com/current?access_key=YOUR_ACCESS_KEY&query=country.name)
on line 5.
Remove the params: {} on lines 6-9

Try: API Request
url: http://api.weatherstack.com/current?access_key=YOUR_ACCESS_KEYf&query=New%20York
From Documentation:
https://weatherstack.com/documentation

Related

Getting "TypeError: Failed to fetch" with some url

I'm facing "TypeError: Failed to fetch" errors in my React App.
Depending on the url of the query I run I sometimes encounter the error, although the query does return a valid result when I test it in my browser.
Here are two examples with two sample URL:
(function(){
var GetRequestResult = function (url) {
return fetch(url, {
headers: { 'Access-Control-Allow-Origin': '*'}})
.then(response => response.text())
.then(text => console.log(text))
.catch(error => console.log(error))
};
this.GetRequestResult = GetRequestResult;
})(this);
console.log(GetRequestResult('https://jsonplaceholder.typicode.com/comments?postId=1')); // Works
console.log(GetRequestResult('http://api.plos.org/search?q=title:DNA')); // Returns 'TypeError: Failed to fetch'
So I have two questions:
Why the first one works and not the second ?
My final need is to retrieve a response from Google's Recaptcha API (https://developers.google.com/recaptcha/docs/verify) using the URL: https://www.google.com/recaptcha/api/siteverify . I am encountering the error on this url also.
I guess it's related to CORS (I tried to modify the Headers of my requests, to define https://www.google.com as a proxy, to use different methods to execute the requests ...) but without success. Any idea to solve this problem ?
The problem is solved.
I was trying to call the Google Recaptcha API (https://www.google.com/recaptcha/api/siteverify) from my frontend.
Due to Google's CORS policy this only seems possible from the backend side.
async function getRequest() {
fetch('https://api.plos.org/search?q=title:DNA')
.then( res => res.json())
.then( data => console.log(data.response.docs))
.catch( e => console.log(e))
}
The following code is working in nodejs

Cypress stubbing XHR response based on request

I am beginer in Cypress and looking for help with network stubbing.
My UI tiggers 3 API calls concurrently upon clicking on a button in the UI. All 3 API are of same endpoint, BUT each of them have different request and response.
I am able to stub the json response using cy.fixture, cy.server() and cy.route().
My need is to 'only stub the 3rd XHR call response', but, my test stubs all three because of the same endpoint.
Any suggessions on how could I test it using any condition ? example - Only stub the call if the parameters of 'request'XHR is 'XXX'?
I tried using before and after the .click() of submit button but that didn't work.
cy.fixture('myfixture').then(jsonresponse => {
function FixtureController(request, response) {
if (cy.url().request.body.contains("XXX")) {
cy.server()
cy.route('POST', 'URL', jsonresponse).as('myalias')
I appreciate any support.
Thanks!
You can use cy.intercept to match based on several things, including query parameters.
cy.intercept({
url: 'http://example.com/search*',
query: { q: 'expected terms' },
}, { fixture: 'myfixture' } )
If you need to match on the request body contents, you can use a route handler to specify.
cy.intercept('http://example.com/search*', (req) => {
if (req.body.contains('some string') {
req.reply({ statusCode: 200, fixture: 'myfixture' });
} else {
req.reply(); // not providing any input forwards the request as normal
}
});
Check out the cy.intercept documentation for more info.

Fetch GET request hitting .catch() on anything but 200 response

I have a redux store set up with actions to handle loading accounts. The action calls a service like so:
const requestOptions = {
method: 'GET',
headers: authHeader()
};
return fetch(`http://localapi.co.uk/api/account/load/${account_id}`, requestOptions)
.then(handleResponse)
.then(account => {
if(account.account.id) {
localStorage.setItem('account', JSON.stringify(account))
}
return account;
})
.catch(redirectToLogin)
Handle response is simply a function that checks the .status and .ok properties of the response and either displays an error or logs out if the response status is 401. This works perfectly fine for POST requests. When I hit my login route, any response hits the first .then(handleResponse) and deals with it.
When I send a GET request instead like above 404s, 401s, 500s.. etc all skip the .then(handleResponse) and instead jump to my catch. The problem that causes is that because catch doesn't actually give me a response object to work with I can't check the status - I want to do different things depending on whether the get was a 401 (I want to logout) or a 500 (I want to display a user error stating what went wrong) for example.
Is there a solution that will allow me to get a response or stop my GET requests hitting the .catch and instead hit the response handler I've written?
I'm using:
a Laravel 5.7.20 back-end
a React 16.7.0 front-end
running local node server with npm start
How about having a clean async/await function. Waiting till you JSON data becomes ready and then having the rest of your if logic or returning the account object from the function and moving the rest of the logic to the caller function. Something like this:
async myFunc({ account_id}) {
const url = `http://localapi.co.uk/api/account/load/${account_id}`;
const response = await fetch(url, { headers: headers: authHeader() });
const account = await response.json();
// return account (recommended);
// Place your if logic here (not recommended because its not clean)
}

React Axios Appends Window Origin To Provided Url (json-server)

I have a weird behaviour while integrating a json-server api with axios.
I use json-server to serve a db.json file
json-server --watch db.json --port 4000
and in my react application I use axios to call "http://localhost:4000/tasks"
Testing it on postman, the API returns results and it is working fine.
but using the code snippet below (axios) it concatenates both domains of the react app and the api Url to the request.
try {
return axios({
method: 'GET',
url: `http://localhost:4000/tasks`
}).then((response) => {
debugger;
return response;
});
} catch (error) {
return new Error('Failed to retrieve Tasks');
}
I check in the browser network and I the request Url like that
Request URL: http://localhost:3000/http//localhost:4000/tasks
and therefore throws a not found - 404 exception
Any idea why is this happening?
The weird thing is that When I use another API like star wars api "https://swapi.co/api/people/1", It works like a charm.
Thanks in advance...
I've fixed this problem by using environment variables.
I just created a ".env.development" file and added "REACT_APP_API_BASEURL = 'http://localhost:4000'".
And then I used it as follows:
try {
return axios({
method: 'GET',
url: `${process.env.REACT_APP_API_BASEURL}/tasks`
}).then((response) => {
debugger;
return response;
});
} catch (error) {
return new Error('Failed to retrieve Tasks');
}
and it worked perfectly.
Just faced this issue, it's because the url used in axios is wrong. In this case, the url in the original question is
http://localhost:3000/http//localhost:4000/tasks
Notice http//localhost:4000/tasks this is missing a colon after http. Fixing the url will fix this issue in case someone else is facing this again

React, Fetch-API, no-cors, opaque response, but still in browser memory

I've been trying to make an React site, which would fetch a GET-response from API and print it out to my .html-file. I've managed to fetch the file just right, but i can't access the JSON-data server sends me.
If i use no-cors in my Fetch-request, i get an opaque response containing pretty much nothing, but if i go to Developer tools i can find my data there and read it. If i do use cors, almost same thing. I get an 403-error, but my data is in the browser memory, but my code doesn't print it out. I can find the response from Network in developer tools.
Why does the server give me an error, but still i get my data? And how can i access it, if it's in the browser?
class Clock extends React.Component {
constructor(props) {
super(props)
this.state = {data2: []}
this.apihaku = this.apihaku.bind(this)
}
componentDidMount() {
this.apihaku(),
console.log("Hei")
}
apihaku () {
fetch('https://#######/mapi/profile/',
{method: 'GET', mode:'no-cors', credentials: 'include',
headers: {Accept: 'application/json'}}
).then((response) => {
console.log(response);
response.json().then((data) =>{
console.log(data);
});
});
}
render() {
return <div>
<button>Button</button>
</div>
}}
ReactDOM.render(
<Clock />,
document.getElementById('content')
)
EDIT: Error images after trying out suggestions
https://i.stack.imgur.com/wp693.png
https://i.stack.imgur.com/07rSG.png
https://i.stack.imgur.com/XwZsR.png
You're getting an opaque response, because you're using fetch with mode: 'no-cors'. You need to use mode: 'cors' and the server needs to send the required CORS headers in order to access the response.
Fetch is doing exactly what the documentation says it's supposed to do, from Mozilla:
The fetch specification differs from jQuery.ajax() in two main ways:
The Promise returned from fetch() won’t reject on HTTP error status
even if the response is an HTTP 404 or 500. Instead, it will resolve
normally (with ok status set to false), and it will only reject on
network failure or if anything prevented the request from completing.
By default, fetch won't send or receive any cookies from the server,
resulting in unauthenticated requests if the site relies on
maintaining a user session (to send cookies, the credentials init
option must be set). Since Aug 25, 2017. The spec changed the default
credentials policy to same-origin. Firefox changed since 61.0b13.
So you need to use CORS, otherwise you get an opaque response (no JSON), and then 403 to me suggests that you haven't authenticated properly. Test your API with Postman, if I had to take a guess I'd say the API isn't sending the cookie because it's a GET request, so no matter how well you set your headers on the client it won't work. Try it as a POST instead. GET requests should really only be used to drop the initial HTML in the browser. I think for your headers use these, include the creds that the API sends and allow the domain to be different.
mode: "cors", // no-cors, cors, *same-origin *=default
credentials: "include", // *same-origin
Try this and see where is the error happening i believe in the parsing but lets check and see
fetch(https://#######/mapi/profile/, {
method: "GET",
headers: {
"Content-Type": "application/json"
},
credentials: "include"
})
.then((response) => {
console.log(response);
try {
JSON.parse(response)
}
catch(err){
console.log("parsing err ",err)
}
})
.catch((err)=>{
console.log("err ",err)
});
I had a similar issue, this kind of problem happend when a HTTP port try to send request to a HTTPS endpoint, adding a "mode:'no-cors'" doesn't do what is SOUND doing but rathere when the documentation says.
I fixed the issue by allowing in my API Application for calls from my HTTP port
(i'm using a .net 6 as an API in debugging mode, my code look like this https://stackoverflow.com/a/31942128/9570006)

Resources