I'm working on a project right now, i need to create a qrcode that contains a specific information in NodeJS. I have started by creating the canvas in HTML, and take it in NodeJS
<canvas id="canvas" width="300" height="300"></canvas>
And then in my NodeJS file, i'm launching my function
const fs = require('fs');
const qrcode = require('qrcode');
module.exports = {
generateQr: function(link){
var canvas = new qrcode(document.getElementById('canvas'));
qrcode.toCanvas(canvas, link, function (error) {
if (error) console.error(error)
console.log('success!');
});
}
};
Unfortunately, i got the error :
ReferenceError: document is not defined
From the above code, does it look correct ? Does the Qrcode get the data i'm passing, and then what should i do so the QR-code appear in my HTML ?
Thank you for your help
document is a browser-specific global object, you can't access it in node
In node environment, you could generate an image with QR code and use it.
Example:
Async/Await style:
const fs = require('fs');
const qrcode = require('qrcode');
module.exports = {
generateQr: async link => {
const qrCodeDataUrl = await qrcode.toDataURL(link);
// ...
}
};
Promise style:
const fs = require('fs');
const qrcode = require('qrcode');
module.exports = {
generateQr: link => {
qrcode.toDataURL(link)
.then(data => {
const qrCodeDataUrl = data;
// ...
})
.catch(err => {
console.error(error);
// ...
});
}
};
Callback style:
const fs = require('fs');
const qrcode = require('qrcode');
module.exports = {
generateQr: link => {
qrcode.toDataURL(link, function(err, data) {
if (error) console.error(error);
const qrCodeDataUrl = data;
// ...
});
}
};
To render it in an HTML-file you could use template-engine of your choice:
Example with ejs:
const ejs = require('ejs');
// In some route
const qrCodeDataUrl = await generateQr('some link');
const html = ejs.render('<img src="<%= qrCodeDataUrl %>" />', {qrCodeDataUrl});
res.header('Content-Type', 'text/html');
res.send(html);
// ...
Note: It's a simplified example. Please check ejs docs for more details
Related
I got some data (articles) from website after scraping with cheerio. I can see it as json file on terminal.
How can I render it to Dom? How can get to see it on the console on the browser?
It's a simple app with only index.js file and at the moment.
Thanks!
I have console log it to terminal like so:
res.json(articles);
console.log(articles)
index.js looks like this:
const PORT = process.env.PORT || 8000;
const express = require("express");
const axios = require("axios");
const cheerio = require("cheerio");
const app = express();
const webpages = [{
name: "ynet",
address: "https://www.ynet.co.il/sport/worldsoccer",
}]
const articles = [];
webpages.forEach(webpage => {
axios
.get(webpage.address)
.then((res) => {
const html = res.data
const $ = cheerio.load(html)
$('div.slotView', html).each(function () {
const title = $(this).text();
const url = $(this).find('a').attr("href");
const img = $(this).find('img').attr('src')
articles.push({
title,
url,
img,
source: webpage.name
});
});
}).catch((err) => console.log(err));
});
app.get("/", (req, res) => {
res.json(articles);
console.log(articles)
})
app.listen(PORT, () => {
console.log(`server runnig on PORT ${PORT}`);
});
I have added an app.js file, querySelector the id from div HTML file, and fetched it like so:
const ynet = document.querySelector('#ynet');
fetch('http://localhost:8000/ynet')
.then(response => response.json())
.then(data => {
data.forEach(element => {
const item = `<a href = "${element.url}" target="_blank"><div class="wrapper"><h3>` +
element.source +
`</h3><p class="text">` +
element.title +
`<img src="${element.img}" alt=""></p></div ></a>`
ynet.insertAdjacentHTML("beforeend", item)
});
console.log(data)
})
.catch(err => {
console.log(err)
})
i am still new in node js, and i am trying to make some backend with file upload/ image upload function that can be stored in sql, i am trying using multer but it cant read my file while testing in postman body. anybody can help me where i do wrong?
here is my controller
const { db } = require('./db');
const bodyParser = require('body-parser');
const getgambar = (req, res) => {
const sqlQuery = "SELECT * FROM gambar";
db.query(sqlQuery, (err, result) => {
if (err) {
console.log(err);
} else {
res.send(result);
console.log(result);
}
});
};
const addgambar = (req,res) => {
const idimg = req.body.idimg;
const gambar = req.file.gambar;
console.log()
const sqlQuery = "INSERT INTO image (idimg,gambar) VALUE (?,?)";
db.query(sqlQuery, [idimg,gambar], (err, result) => {
if (err) {
res.send({
message: "error",
err
})
} else {
res.send({
message: "YES"
})
}
});
};
module.exports = {
getgambar,
addgambar,
};
here is my route
const express = require('express');
const router = express.Router();
const multer = require('multer');
const path = require('path');
const ctrl = require('./gambarctrl');
const storange = multer.diskStorage({
destination: './uploads',
filename: (req, file, cb) => {
return cb(null, `${file.fieldname}_${Date.now()}${path.extname(file.originalname)}`)
}
})
const upload = multer({
storange: storange
})
router.get('/image/display', ctrl.getgambar)
router.post('/image',upload.single('gambar'), ctrl.addgambar)
module.exports = router;
and here my index
const { db } = require('./db');
const express = require('express');
const bodyParser = require('body-parser')
const cors = require('cors');
const app = express();
const fileUpload = require('express-fileupload');
const gambarroute = require ('./gambarroute');
const multer = require('multer');
app.use(cors());
app.use(express.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(gambarroute);
app.listen(3000, () => {
console.log('on port 3000!');
});
i am still quite new in node js and i am still searching for tutorial, i appriciate for the help.
Two problems here...
Multer puts the single uploaded file into req.file so you should use
const gambar = req.file; // no `.gambar`
Assuming your DB column is a BLOB or BINARY type, you need to provide a Buffer.
Since you're storing the images within the DB, you don't need to use DiskStorage. Use MemoryStorage instead which provides a Buffer out-of-the-box
const upload = multer({
storage: multer.memoryStorage(), // watch your spelling
})
Then bind the .buffer property in your query.
db.query(sqlQuery, [idimg, gambar.buffer], (err, result) => {
// ...
});
To respond with the image from Express, use something like this
router.get("/image/display/:id", (req, res, next) => {
db.query(
"SELECT `gambar` FROM `image` WHERE `idimg` = ?",
[req.params.id],
(err, results) => {
if (err) {
return next(err);
}
if (!results.length) {
return res.sendStatus(404);
}
// set the appropriate content type
res.set("Content-Type", "image/jpg");
res.send(results[0].gambar);
}
);
});
and from the frontend...
<img src="http://localhost:3000/image/display/some-id" />
i use that code to download csv from google trends using apify js, but it doesn't work, could you help me?
the result is a csv with a wrong content.
i try to get all csv from google trends.
const path = require('path');
const downloadPath1 = path.resolve(__dirname, './downloads');
const fs = require('fs');
try{
const util = require('util');
await util.promisify(fs.mkdir)(downloadPath1);
}
catch( e){
}
await page.setRequestInterception(true);
//await page.click(csvSelector);
await page.waitForSelector(csvSelector)
const hrefElement = await page.$(csvSelector);
await hrefElement.click();
const xRequest = await new Promise(resolve => {
page.on('request', async interceptedRequest => {
const type = interceptedRequest.resourceType();
log.info(type)
if ( type == "xhr" ) {interceptedRequest.abort();
resolve(interceptedRequest);}
else interceptedRequest.continue();
});
});
log.info(xRequest._url);
const request = require('request-promise');
const options = {
encoding: null,
method: xRequest._method,
uri: xRequest._url,
body: xRequest._postData,
headers: xRequest._headers
}
/* add the cookies */
const cookies = await page.cookies();
options.headers.Cookie = cookies.map(ck => ck.name + '=' + ck.value).join(';');
const response = await request(options);
fs.writeFileSync(downloadPath1+'/binary.csv', response);
const fileObjs = fs.readdirSync(downloadPath1, { withFileTypes: true });
console.log("\nCurrent directory files:");
fileObjs.forEach(file => {
console.log(file);
});
// There won't be more files so let's pick the first
const fileData = fs.readFileSync(downloadPath1+`/${fileObjs[0].name}`);
log.info(fileData);
// Now we can use the data or save it into Key-value store.
await Apify.setValue('MY-Csv.csv', fileData, { contentType: 'application/csv'});
i hope that someone can propose a solution for this thanks
The problem is in db.js because it's trying to load something from db which does not exist.
In my index.js page:
const dataB = require("./db").getAllProducts;
app.get('/scrapper', async (req, res) => {
const Myobjects = await dataB.getAllProducts();
res.send(Myobjects)
})
And in my db.js page:
async function getAllProducts() {
const connection = await getConnection();
const pageRepo = connection.getRepository(Crawlers);
const pages = await pageRepo.find();
connection.close();
return pages;
}
async function InsertScrappedData(texte, image, price){
const connection = await getConnection();
const page = new Crawler();
page.texte = texte;
page.image = image;
page.price = price;
const crawlertrepo=connection.getRepository(Crawlers);
const res=await crawlertrepo.save(Crawlers);
Console.log('saved',res);
const Allpages = await crawlertrepo.find();
connection.close();
return Allpages;
}
Exporting my functions
module.exports = [
getAllProducts,
InsertScrappedData
]
module.exports is an object type, not an array, so you need to use curly brackets when assigning it.
module.exports = {
getAllProducts,
InsertScrappedData
}
Relevant documentation
This is actually a condensed form of assigning the getAllProducts function to the getAllProducts key of a new object and then assigning that object to module.exports
// Equivalent but unnecessarily verbose
module.exports = {
getAllProducts: getAllProducts,
InsertScrappedData: InsertScrappedData
}
I'm a new learner to express js and sequelizejs. I successfully migrate table in my database so the connection is fine I guess.
Here is my code.
https://github.com/Picks42/express-test
Please review this file
https://github.com/Picks42/express-test/blob/master/models/user.js
Then review this one
https://github.com/Picks42/express-test/blob/master/controller/test.js
Let me know what's the issue.
// all the models using your index.js loader
const models = require('../models');
// the user model, note the capital User since
const M_Bank = models.User;
exports.getTest = function(req,res){
return M_Bank
.findAll()
// don't use M_Bank here since you are getting an array of Instances of the Model
.then(users => res.status(200).send(users))
.catch((error) => {
console.log(error.toString());
res.status(400).send(error)
});
/* this will never execute because it is after the return
exports.index = function (request, response, next) {
response.json((M_Bank.findAll()));
};
*/
};
If you have the option of using async/await it makes for more readable code.
const models = require('../models');
const M_Bank = models.User;
exports.getTest = async function(req, res) {
try {
const users = await M_Bank.findAll();
return res.status(200).send(users);
} catch (err) {
console.log(err.toString());
return res.status(400).send(err);
}
};
You should get rid of the .User field in the 3rd line. because you've exported User itself from the models/user file.
Also, I recommend you not to mess with variables names. M_Bank variable doesn't speak itself
const M_Bank = require('../models/user');
exports.getTest = function(req,res){
return M_Bank
.findAll()
.then(M_Bank => res.status(200).send(M_Bank))
.catch((error) => {
console.log(error.toString());
res.status(400).send(error)
});
exports.index = function (request, response, next) {
response.json((M_Bank.findAll()));
};
};