well, in the code you can see that when the first object is saved, the id comes out undefined and then the other objects start to come out fine, I was thinking about it but I can't fix it, the problem is in the save() function in the part that pushes the newProduct does anyone realize what the problem is?
const fs = require("fs");
class Container {
constructor(fileName) {
this.fileName = fileName;
}
async createEmptyFile() {
fs.writeFile(this.fileName, "[]", (error) => {
if (error) {
console.log(error)
} else {
console.log(`File ${this.fileName} was created`);
}
});
}
async readFile() {
try {
const data = await fs.promises.readFile(this.fileName, 'utf-8');
return JSON.parse(data);
} catch (error) {
if (error) {
this.createEmptyFile();
} else {
console.log(`Error Code: ${error} | There was an unexpected error when trying to read ${this.fileName}`);
}
}
}
async save(title, price, thumbnail) {
try {
const data = await this.readFile();
const newProduct = {
title,
price,
thumbnail,
id: data.length + 1
}
data.push(newProduct);
await fs.promises.writeFile(this.fileName, JSON.stringify(data));
return newProduct.id;
} catch (error) {
console.log(`Error Code: ${error.code} | There was an error when trying to save an element`);
}
}
}
const container = new Container("products.json");
const main = async () => {
const id1 = await container.save(
"Regla",
75,
"https://rfmayorista.com.ar/wp-content/uploads/2020/03/REGLA-ECONM_15-CM.-600x600.jpg"
);
const id2 = await container.save(
"Goma",
50,
"https://image.shutterstock.com/image-photo/rubber-eraser-pencil-ink-pen-260nw-656520052.jpg"
);
const id3 = await container.save(
"Lapicera",
100,
"https://aldina.com.ar/wp-content/uploads/2020/08/bic-cristal-trazo-fino-azul-1.jpg"
);
console.log(id1, id2, id3);
};
main();
From already thank you very much
In the readFile method you need to return something on the catch statement in order to get consistent return values
async readFile() {
try {
const data = await fs.promises.readFile(this.fileName, 'utf-8');
return JSON.parse(data);
} catch (error) {
if (error) {
this.createEmptyFile();
} else {
console.log(`Error Code: ${error} | There was an unexpected error when trying to read ${this.fileName}`);
}
// returns [] because this seems to be the default value for the file in createEmptyFile
return []; // Add this line
}
}
What happens is practice is: the file doesn't exist, the try statement fails, then the catch statement and the function don't return anything thus undefined.
Related
Caching patch code
import mongoose, { mongo } from 'mongoose';
import { createClient } from 'redis';
//redis init
const redisUrl = 'redis://127.0.0.1/6379'
const client = createClient();
client.on('error', (err) => console.log('Redis Client Error', err));
client.connect();
client.on("connect", (err) => {
if (err) throw err;
else console.log("Redis Connected!");
});
mongoose.Query.prototype._exec = mongoose.Query.prototype.exec;
mongoose.Query.prototype.cache = function (options = {}) {
this.useCache = true;
this.hashKey = JSON.stringify(options.hashKey || '')
return this;
}
mongoose.Query.prototype.exec = async function () {
if (!this.useCache) {
console.log();
return await mongoose.Query.prototype._exec.apply(this,arguments);
}
const key = JSON.stringify(Object.assign({}, this.getQuery(), {
collection: this.mongooseCollection.name + this.op,
}))
//See if we have a value for 'key' in redis
let cachedValue = await client.sendCommand(['HGET', this.hashKey, key])
//return if present
if (cachedValue) {
cachedValue = JSON.parse(cachedValue);
//Hydrating Model and Arrays of Models
return Array.isArray(cachedValue) ?
cachedValue.map(d => new this.model(d)) :
this.model(cachedValue);
}
//otherwise set into redis
let result = await mongoose.Query.prototype._exec.apply(this,arguments);
await client.hSet(this.hashKey, key, JSON.stringify(result));
client.expire(this.hashKey, 3000)
return result;
}
let projects = await db.Project.find({
companyId: userCompanyId,
})
.limit(limit)
.cache({ hashKey: userCompanyId });
Trying to apply caching to a paginated response, however the caching function is working whereas others like skip and limit are not working.
I tried the solution from mongoose.Query.prototype.exec() patching not working with populate however it did not resolve the issue.
I am trying to save to json the values returned from indeed api. I use indeed-scraper code from github https://github.com/rynobax/indeed-scraper
My code:
... required files ...
const parsedResults = []
indeed.query(queryOptions).then(response => {
response.forEach((res,i) => {
setTimeout(function(){
let url = res.url
let resultCount = 0
console.log(`\n Scraping of ${url} initiated...\n`)
const getWebsiteContent = async (url) => {
try {
const response = await axios.get(url)
const $ = cheerio.load(response.data)
...get scraped data...
parsedResults.push(metadata)
} catch (error) {
exportResults(parsedResults)
console.error(error)
}
}
getWebsiteContent(url)
}
, i*3000);
});
});
const outputFile = 'data.json'
const fs = require('fs');
const exportResults = (parsedResults) => {
fs.writeFile(outputFile, JSON.stringify(parsedResults, null, 4), (err) => {
if (err) {
console.log(err)
}
console.log(`\n ${parsedResults.length} Results exported successfully to ${outputFile}\n`)
})
}
parsedResults is not accessible in last portion of script, so to save as json file.
Any help appreciated!
when i call the function .get returns an empty object. When i use console.log returns the database but when the function reach returns result is {}.
let { connection, mongoose } = require("../../../config/mongodb");
let { Schema, model } = mongoose;
let { productosSchema } = require("../../../schemas/productos");
let productosSchemaModel = new Schema(productosSchema);
let Productos = new model("productos", productosSchemaModel);
class ProductosService {
constructor(url) {
this.url = url;
}
async getProds() {
try {
const allProds = await Productos.find({}).sort({ producto: 1 });
return prods;
} catch (error) {
console.log(error);
}
}
}
As #CertainPerformance said, your variable name is allProds, not prods. Simply change the return from return prods; to return allProds; and it should work. See below for the complete code:
const { mongoose } = require('../../../config/mongodb');
const { Schema, model } = mongoose;
const { productosSchema } = require('../../../schemas/productos');
const productosSchemaModel = new Schema(productosSchema);
const Productos = new model('productos', productosSchemaModel);
class ProductosService {
constructor(url) {
this.url = url;
}
async getProds() {
try {
const allProds = await Productos.find({}).sort({
producto: 1
});
return allProds;
} catch (error) {
console.log(error);
}
}
}
I have a nodeJS server and want to set up a connection and export function to post messages to queue from the js file.
const amqp = require("amqplib");
const url = process.env.RABBITMQ_SERVER;
let channel = null;
amqp.connect(url, (e, conn) =>
conn.createChannel((e, ch) => {
channel = ch;
})
);
module.exports = publishToQueue = (
data,
queueName = process.env.RABBITMQ_QUEUE
) => channel.sendToQueue(queueName, new Buffer.from(data));
process.on("exit", code => {
ch.close();
console.log("closing rabbitmq channel");
});
But when I try to import and use it, I've got empty object {}
hooks: {
beforeCreate (instance) {
console.log(amqp)
amqp(JSON.stringify(instance.toJSON()))
}
}
UPDATE:
thanks HosseinAbha's answer, i've ended up with creating a class and set up connection in constuctor
const amqp = require("amqplib");
const url = process.env.RABBITMQ_SERVER;
class RABBITMQ {
constructor () {
this.connection = null
this.channel = null
this.connect()
}
async connect () {
try {
this.connection = await amqp.connect(url)
this.channel = await this.connection.createChannel()
await this.channel.assertQueue(process.env.RABBITMQ_QUEUE)
await this.channel.bindQueue(process.env.RABBITMQ_QUEUE, process.env.RABBITMQ_EXCHANGE)
await this.channel.assertExchange(process.env.RABBITMQ_EXCHANGE, 'fanout', { durable: true })
} catch (err){
console.log(err)
throw new Error('Connection failed')
}
}
async postData (data) {
if (!this.connection) await this.connect()
try {
this.channel.publish(process.env.RABBITMQ_EXCHANGE, `${data.type}.${data.event_type}`, new Buffer.from(JSON.stringify(data)))
} catch (err){
console.error(err)
}
}
}
module.exports = new RABBITMQ()
Your publishToQueue function should return a promise and it should connect to rabbitMQ before doing anything. Your function should be something like this:
const connectToChannel = async () => {
try {
let connection = await amqp.connect(url)
return connection.createChannel()
} catch (e) {
console.error('failed to create amqp channel: ', e)
}
}
let channel;
module.exports = publishToQueue = async (
data,
queueName = process.env.RABBITMQ_QUEUE
) => {
if (channel == null) {
channel = await connectToChannel();
}
return channel.sendToQueue(queueName, Buffer.from(data));
}
You also don't need to instantiate the Buffer and Buffer.from is enough.
I wonder why I am getting this err/warning even though my code looks okay.
Here's the UserModel I started building:
const fs = require('fs');
class UserModel {
constructor(filename) {
if (!filename) {
throw new Error('Require a filename...');
}
this.file = filename;
try{
fs.accessSync(this.file); //to check if the file exists already
} catch (err) { //if not, make a new file
fs.writeFileSync(this.file, ['']);
}
}
async getAll() {
return JSON.parse(await fs.promises.readFile(this.file,{
encoding: 'utf8'
}));
}
}
//to test the above code
const test = async () => {
const user = new UserModel('users.json');
const data = await user.getAll();
console.log(data);
}
test();
Please help, new to NodeJS world.
Like the comment says, you should put a try/catch around the await in getAll. Like this:
const fs = require('fs');
class UserModel {
constructor(filename) {
if (!filename) {
throw new Error('Require a filename...');
}
this.file = filename;
try{
fs.accessSync(this.file); //to check if the file exists already
} catch (err) { //if not, make a new file
fs.writeFileSync(this.file, ['']);
}
}
async getAll() {
return JSON.parse(await fs.promises.readFile(this.file,{
encoding: 'utf8'
}));
}
}
//to test the above code
const test = async () => {
const user = new UserModel('users.json');
try {
const data = await user.getAll();
console.log(data);
} catch (error) {
// handle error
console.log(error.stack)
}
}
test();