I need help the first object is saved undefined - javascript

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

mongoose.Query.prototype.exec patching causes other Query prototype functions to not work

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.

Run code after executing promise in Javascript

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!

im using mongo and nodeJs Async returns an empty task when i use return. But console.log show me all the data

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);
}
}
}

Module export function that post on RabbitMQ queue

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.

Getting Unhandled Promise Rejection Warning in NodeJS

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();

Categories