I'm creating a script which is going to receive a data from API every 24 hours in specific time.
I'm using node-schedule package
After I trying to see the script in terminal or in chrome console log. I receive an error that request is not defined.
I installed RequireJS already, but the error still appears.
I was trying the example from node-schedule documentation itself, also receiving the same error in terminal.
Where is my mistake and how I can fix it?
Code below:
var schedule = require("node-schedule");
var j = schedule.scheduleJob("*/55 20 * * *", function() {
request(
"GET",
"http://pro-api.coinmarketcap.com/v1/cryptocurrency/listings/latest?CMC_PRO_API_KEY=YOUR-API-KEY"
)
.then((r1) => {
var x1 = JSON.parse(r1.target.responseText);
var BTCdata = x1.data.find((d) => d.symbol === "BTC").quote.USD
.volume_24h; // creating a variable to store a BTC request from API
console.log(BTCdata);
})
.catch((err) => {
console.log(err);
});
});
function request(method, url) {
return new Promise(function(resolve, reject) {
var xhr = new XMLHttpRequest();
xhr.open(method, url);
xhr.onload = resolve;
xhr.onerror = reject;
xhr.send();
});
}
Related
Here is the code for a working firebase cloud function and following is a question about some change I want to make and can't at this point, even after trying several options.
import * as functions from "firebase-functions";
import * as admin from "firebase-admin";
import * as cors from "cors";
const corsHandler = cors({origin: true});
admin.initializeApp(functions.config().firebase);
exports.myFunc = functions.https.onRequest(function(req, resp) {
corsHandler(req, resp, async () => {
const from = String(req.query.from); // Through the URL.
// const from = req.body.from; // I tried this among other things to get the information through a POST but it did not work.
admin.auth().getUserByEmail(from)
.then(function(userRecord) {
console.log("Successfully fetched user data:",
userRecord.toJSON());
})
.catch(function(error) {
console.log("Error fetching user data:", error);
});
});
});
This function can be called using a URL like:
https://us-central1-myapp.cloudfunctions.net/myFunc?from=example#example.com
But what I want is to be able to call it through a POST from a JS page (with XMLHttpRequest) in my web app.
How should I change the function above for that?
For reference, this is the kind of code I am trying to use on the web-app side to call the cloud function (but it is not working):
var xhr = new XMLHttpRequest();
xhr.open("POST", "https://us-central1-myapp.cloudfunctions.net/myFunc", true, 'me#example.com', 'VerySecretPassWord');
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send({"from": "example#example.com"});
xhr.onload = function() {
var data = JSON.parse(this.responseText);
console.log('THE DATA:',data);
};
I am having trouble adjusting the code (using cors) for a firebase cloud function I am working on.
Below is the code for the function:
import * as functions from "firebase-functions";
import * as admin from "firebase-admin";
import * as cors from "cors";
import { on } from "events"
const corsHandler = cors({origin: true});
admin.initializeApp();
exports.myFunc = functions.https.onRequest(function(req, resp) {
corsHandler(req, resp, async () => {
if (req.query.from !== undefined) {
const from = String(req.query.from);
functions.logger.log("From (URL):", from);
} else {
functions.logger.log("req.query.from is undefined");
}
const from = req.body.from;
functions.logger.log("Hello from --myFunc--");
admin.auth().getUserByEmail(from)
.then(function(userRecord) {
console.log("Successfully fetched user data:", userRecord.toJSON());
})
.catch(function(error) {
console.log("Error fetching user data:", error);
});
}); // End corsHandler.
});
When I call this function using this URL in the browser:
https://us-central1-myapp.cloudfunctions.net/myFunc?from=example#example.com
I get what I expect in the logs, that is:
myFunc: From (URL): example#example.com
On the other hand when I call the function using this Ajax code from a web-app:
var xhr = new XMLHttpRequest();
xhr.open("POST", "https://us-central1-myapp. cloudfunctions.net/myFunc", true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send("from=example#example.com");
xhr.onload = function() {
var data = JSON.parse(this.responseText);
console.log('THE DATA:',data);
};
I have a problem, getting the following in the web console logs:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://us-central1-myapp.cloudfunctions.net/myFunc. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing). Status code: 400.
I must be missing something. Can someone point out what it is ?
I finally got it to work, using this code for the Ajax call from the web-app (hoping this might help someone facing the same kind of issue at some point):
var xhr = new XMLHttpRequest();
xhr.open("POST", "https://us-central1-myapp. cloudfunctions.net/ myFunc", true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send(JSON.stringify({
from: 'example#example.com'
}));
xhr.onload = function() {
var data = JSON.parse(this.responseText);
console.log('THE DATA:',data);
};
I'm creating a script which is going to automatically receive data from API and store it in MongoDB at specific UTC time.
I use Node-Schedule for scheduling a task at specific time.
CoinMarketCap API for receiving a real time data.
Problem: I receive an undefined in console every second(since the node-schedule is configured to call the code every second). I was looking for any syntax errors or errors in API and wasn't successful. I understand that I receive undefined cause the function doesn't return anything.
Currently doesn't have any ideas what wrong with it at all.
All API keys and DB username password was correct I checked it as well.
Goal: To have the script which is automatically receives data from API and stores it MongoDB collection.
Full Code
const { MongoClient } = require('mongodb');
const schedule = require('node-schedule');
var XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest;
const saveToDatabase = function(BTCdata) {
const url = 'mongodb+srv://name:password#cluster0-1kunr.mongodb.net/<dbname>?retryWrites=true&w=majority';
MongoClient.connect(url, { useNewUrlParser: true, useUnifiedTopology: true }, (err, db) => {
if (err) throw err;
const dbo = db.db('Crypto');
const myobj = { Name: 'BTC', Volume: 'BTCdata' };
dbo.collection('Crypto-Values').insertOne(myobj, (error, res) => {
if (error) throw error;
console.log('1 document inserted');
db.close();
});
});
};
function request(method, url) {
return new Promise(((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open(method, url);
xhr.onload = resolve;
xhr.onerror = reject;
xhr.send();
}));
}
const j = schedule.scheduleJob('* * * * * *', () => {
request(
'GET',
'http://pro-api.coinmarketcap.com/v1/cryptocurrency/listings/latest?CMC_PRO_API_KEY=API-KEY-HERE',
)
.then((r1) => {
const x1 = JSON.parse(r1.target.responseText);
const BTCdata = x1.data.find((d) => d.symbol === 'BTC').quote.USD.volume_24h; // creating a variable to store a BTC request from API
console.log(BTCdata);
// Saving to database
saveToDatabase(BTCdata);
})
.catch((err) => {
console.log(err);
});
});
EDIT1:
This is a console log of x1 value.
EDIT2:
Was missing this part -
var request = require('request');
After it was added I start receiving a new error in my console which is :
events.js:287
throw er; // Unhandled 'error' event
^
Error: Invalid URI "GET"
at Request.init
at new Request
at request
at Job.job
at Job.Invoke
at Users/path to node modules/node-schedule
at Timeout.onTimeout
EDIT3:
After correction to the code with #Sureshprajapati answer.
New error appears - TypeError: Cannot read property 'responseText' of undefined
Trying to find solution by myself. Still looking for any advice. Thank you.
var requestPromise = require('request-promise');
requestPromise.get({
uri: 'http://pro-api.coinmarketcap.com/v1/cryptocurrency/listings/latest?CMC_PRO_API_KEY=API-KEY-HERE',
json: true
}).then(r1 => {
const x1 = JSON.parse(r1.target.responseText);
const BTCdata = x1.data.find(d => d.symbol === 'BTC').quote.USD
.volume_24h; // creating a variable to store a BTC request from API
console.log(BTCdata);
// Saving to database
saveToDatabase(BTCdata);
}).catch(err => {
console.log(err);
});
request supports both streaming and callback interfaces natively. If you'd like request to return a Promise instead, you can use an alternative interface wrapper for request. These wrappers can be useful if you prefer to work with Promises, or if you'd like to use async/await in ES2017.
request-promise (uses Bluebird Promises)
This module is installed via npm:
npm install --save request
npm install --save request-promise
Coming to modifying your code as per documentation:
var requestPromise = require('request-promise');
requestPromise.get({
uri: 'http://pro-api.coinmarketcap.com/v1/cryptocurrency/listings/latest?CMC_PRO_API_KEY=API-KEY-HERE',
json: true
}).then(x1 => {
const BTCdata = x1.data.find(d => d.symbol === 'BTC').quote.USD
.volume_24h; // creating a variable to store a BTC request from API
console.log(BTCdata);
// Saving to database
saveToDatabase(BTCdata);
}).catch(err => {
console.log(err);
});
I'm new to node and I'm trying to make a simple xhr to a server and print out to the console when it succeeds with this code:
// Code slice of test.js
xhr.open('GET', uri, true);
xhr.onreadystatechange = () => {
if (xhr.readyState === 4) {
console.log("Success!");
} else {
console.log("Waiting...");
}
};
xhr.send();
However, when I run this with node test.js, it only prints out Waiting... once and then never ends execution.
I've tested this code slice in a browser so I know this XHR should work but am I using this wrong?
I am trying to use XHR to track uploading progress, but at my onprogress callback at event.total I only getting Content-Length from response header instead of uploading file size:
xhr.onprogress = (event) => {
console.log('Progress ' + event.loaded + '/' + event.total);
}
I use Multer to handle file uploading and seems it is not avaible to handle file uploading by default:
https://github.com/expressjs/multer/issues/243
So I tried to handle uploading with progress-stream:
var p = progress({ time: 1 });
request.pipe(p);
p.on('progress', function() {
console.log('Progress...');
});
But it works same way, I only get onle "Progress..." at log and at XHR onprogress event.total I have only Content-Length value instead of file size value. Help please, I have no idea how to fix it!
You don't need get the progress in the backend if you want to show the progress, you only need to know what you've sent from your frontend to backend so you can calculate the upload progress.
In your frontend .js or .html, try something like this:
var formData = new FormData();
var file = document.getElementById('myFile').files[0];
formData.append('myFile', file);
var xhr = new XMLHttpRequest();
// your url upload
xhr.open('post', '/urluploadhere', true);
xhr.upload.onprogress = function(e) {
if (e.lengthComputable) {
var percentage = (e.loaded / e.total) * 100;
console.log(percentage + "%");
}
};
xhr.onerror = function(e) {
console.log('Error');
console.log(e);
};
xhr.onload = function() {
console.log(this.statusText);
};
xhr.send(formData);
In the backend you only need a simple endpoint like this:
app.post('/urluploadhere', function(req, res) {
if(req.files.myFile) {
console.log('hey, Im a file and Im here!!');
} else {
console.log('ooppss, may be you are running the IE 6 :(');
}
res.end();
});
Multer is also necessary and remember, xhr only works in modern browsers.