I am trying to make 2 fetch requests inside a function which runs periodically.
exports.scheduledPay = functions.pubsub.schedule('1 of month 07:00').timeZone('America/New_York').onRun((context) => {
//1. fetch for getting token ...
//2. fetch for making Paypal batch request using that token
fetch("https://api.sandbox.paypal.com/v1/payments/payouts", {
method: 'POST',
headers: {"Authorization":"Basic QWJ4aUhTaWM5cmp2NUpQdEV2WUhaMi1hWmVySWFoTHdDVDEza004UURLY3RMWGtXN3lpTFRfVGpFVllVMXB5NFhKcGtxXzdYSVpYRmhkaFc6RVBUbUVZSWg2OE1FVG9FSjEyT0lHdzFKWkFGNTVza2Q2SjNiRmpLYkxMTEJiOTY3akRhQkdRREt1S29yTWN4amZ3Rm00X0VCa1dvUzJkejn="},
body: {"grant_type":"client_credentials"},
redirect: 'follow'
})
.then(response => {return response.text()})
.then(result => {console.log(result);
return null;
})
.catch(error => console.log('error', error));
}
However, I keep on getting this error.
ReferenceError: fetch is not defined
at exports.scheduledAward.functions.pubsub.schedule.timeZone.onRun (/workspace/index.js:230:5)
at cloudFunction (/workspace/node_modules/firebase-functions/lib/cloud-functions.js:130:23)
at Promise.resolve.then (/layers/google.nodejs.functions-framework/functions-framework/node_modules/#google-cloud/functions-framework/build/src/invoker.js:199:28)
at process._tickCallback (internal/process/next_tick.js:68:7)
Cloud Functions run in a nodejs JavaScript environment. This is very different than browser JavaScript environments. You won't have access to the fetch() function that browsers provide - that explains the error message.
What you will need to do instead is use some other type of HTTP client library built for nodejs. There are a lot of popular options out there, and I recommend doing a web search to find one.
Related
Context:
I'm building a app that can plot graph structures in electron with react. My backend is some Matlab code that can perform analysis on the graph struct. I'm using flask as the middle man communicating between them.
In the GUI i have a button that should be able to load the data that is provided in a excel file to the GUI. This should be done by a post request that uses a matlab script to load the data from the excel file and then returns this to javascript.
I have tried using something like this:
fetch('http://localhost:5000/getGriddata', {
method : 'POST',
headers : {
'Content-Type' : 'application/json'
},
body : JSON.stringify(fileObj.path)
}).then(response => response.json())
.then(data => setGriddata(data))
.catch(error => console.log(error));
The problem is that this code won't wait for the flask function to be finished. The flask function takes about 10 seconds depending on the graph size. Therefor i want to make this call in sync with my javascript code so that after the request, i can assure that the new griddata is defined.
Question:
Is there some way to ensure this when using fetch?
Do i need to find a different way of connecting to flask, if so what would that be?
Solution:
Instead of using the fetch api, another post brought me to the XMLHttpRequest. This works synchronously if the parameter is set to false.
With this my code looks like this:
var request = new XMLHttpRequest();
request.open("POST",'http://localhost:5000/getGriddata',false);
request.setRequestHeader('content-type', 'application/json');
request.send(JSON.stringify(fileObj.path));
console.log(request.response)
console.log(request.responseText)
setGriddata(JSON.parse(request.responseText))
Instead of using callbacks, try using async/await
const fetchGridData = async () => {
try {
const response = await fetch('http://localhost:5000/getGriddata', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(fileObj.path)
});
const result = await response.json();
setGriddata(result)
} catch(error) {
console.error("fetchGridData =>", error)
}
}
I'm trying to run a simple example consuming the list of page slugs from WordPress REST API, but I'm facing a very strange behavior.
I have an async function getPageList() that simply calls the WP API using fetch.
const getPages = async (path) => {
return await fetch(process.env.NEXT_PUBLIC_WP_API_URL + "/pages?_fields=slug", {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
}
})
}
Running through the browser, I have no issues calling this method and getting the results:
export default function Example() {
useEffect(() => {
getPageList().then(pages => console.log(pages))
}, []); // OK
return null
}
However if I try to execute the same call from the server, inside getStaticProps, I receive the error FetchError: request to http://localhost:8000/wp-json/wp/v2/pages?_fields=slug failed, reason: connect ECONNREFUSED 127.0.0.1:8000
This is the code snippet:
export async function getStaticProps() {
const pages = await getPageList()
//(....)
}
If I query this URL using Postman or just copy and paste in the browser, it works seamlessly too.
Any ideas on what's going on?
I'm using create-next-app, Node 16.13.0, Wordpress 5.8.2, PHP 7.4.3 running using local development server (php -S localhost:8000)
Thank you in advance!
This was related to how I was initiating my PHP built-in server. Changing it to php -S 127.0.0.1:8000 instead of localhost:8000 fixed the problem.
so i was trying to make 2 different projects first one is my ecommerce frontend made with next js and second one is ecommerce dashboard which is also made with next js.
But when i am trying to post products from my dashboard to my ecommerce frontend nothing is happening even also I am not getting any error in console that's why i am unable to understand what is the problem.
Can anyone help me in this ? The fetch code is below.
const handelSubmit = async (e) => {
e.preventDefault();
console.log("clicked");
fetch(`http://192.168.43.53:3000/api/products`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(
name,
price,
// mediaUrl,
description,
collect,
),
})
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.1/umd/react-dom.production.min.js"></script>
Nextjs apis only work with the same origin by default, see Nextjs api Caveats for more info.
If you want to make a fully public api with Nextjs, you have to add cors, see Api Middlewares. Your code will look something like:
import Cors from 'cors'
// Initializing the cors middleware
const cors = Cors({
methods: ['GET', 'HEAD'],
})
// Helper method to wait for a middleware to execute before continuing
// And to throw an error when an error happens in a middleware
function runMiddleware(req, res, fn) {
return new Promise((resolve, reject) => {
fn(req, res, (result) => {
if (result instanceof Error) {
return reject(result)
}
return resolve(result)
})
})
}
If your backend api isn't defined with Nextjs, please share the code of your requested api endpoint and also the technology it uses.
I think the data you are posting needs to be in JSON first.
body: JSON.stringify(
key:value,
key1:value1
)
Im trying to make a discord bot where if you type -cr into the chat, it takes the Arguments of the user (Being the Clash Royale Player's player tag) and would then use the package node-fetch to receive data with my specified endpoint. I am constantly running into the error of { reason: 'accessDenied', message: 'Invalid authorization' }. Im rather new to this stuff, especially API's, but im hoping to access certain data which I can decide later on (Which I know how to do). My code is :
const fetch = require('node-fetch')
module.exports = {
name: 'clash',
aliases: ['cr', 'clashroyale'],
category: 'This',
utilisation: '{prefix}clash',
async execute(client, message) {
var msgArgs = message.content.slice(this.name.length + 1)
var endpoint = `/players/${msgArgs}`
var url = `https://api.clashroyale.com/v1`
var token = `hidingmytoken`
fetch(url + endpoint, {
method: 'POST',
headers: {
"Authorization": token
}
}).then(data => data.json()).then(json => {
console.log(json)
})
},
};
The message parts with msgArgs and discord sides all work but fetching that clash Royale API is a big hurdle for me. The API for Clash Royale can be found here https://developer.clashroyale.com/#/documentation and Im just generally stuck on this whole concept. Im using version 2.6.6 of node-fetch so I can use the require() method which should work if that does matter. In general, how can I pass my token properly to receive that API data?
Since the Clash Royale API uses bearer authentication, you need to specify that it will be a bearer token.
headers: {
'Authorization': `Bearer ${token}`
}
I've implemented the following functionality. The code is written in GO but you can copy the logic and translate into your language.
The library have the following functionality:
Login
Token generation
Token list
Token delete
https://github.com/alessiosavi/GoClashRoyale/blob/master/api/auth.go
When use python requests and send the following
outs = requests.get("https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=32.78257453407587,-117.11499507124117&radius=15000&keyword=Paddle+Board+Rentals&key=MY_KEY")
I get a status 200 and results.
When I issue with Axios
async getPlaces(point, radius, keywords, type=""){
const url = this.urlBuilder(point, radius, keywords, type);
const response = await axios.get(url)
.then(res => {return res})
.catch(err => {return err});
return response
}
And the url is the exact same in the python above, I get
Error: Network Error
Is there a default header in python that could be causing the difference between the two requests?
Edit:
Using console.log I was able to get this error
Error: Cross origin http://localhost forbidden
So there's an issue from running google places request with fetch or axios because they are coming from local host.
The issue was that google will not allow users to make these network calls over https with javascript. You must use the google places api.