Access array values after knex SELECT - javascript

I have the following code snippet in an Electron app to retrieve a given column in a sqlite3 database:
database.js
var database = require("knex")({
client: "sqlite3",
connection: {
filename: path.join(__dirname, 'db/food.db')
},
useNullAsDefault: true
});
const fetchItems = (colName) => {
let itemList = database.select(colName).from('food')
itemList.then(() => {
// console.log(itemList);
return itemList;
}).catch((err) => {
console.log(err)
return [];
})
}
When I try accessing the array itemList, I got a message undefined. When I try printing it out to console, it shows lengthy info of the database object as following:
Builder [object] {
client: Client_SQLite3 {
config: { client: 'sqlite3', connection: [Object], useNullAsDefault: true },
logger: Logger {
_inspectionDepth: 5,
_enableColors: true,
_debug: undefined,
_warn: undefined,
_error: undefined,
_deprecate: undefined
},
connectionSettings: {
filename: '/home/.../db/food.db'
},
connectionConfigExpirationChecker: null,
driver: {
Database: [Function: Database],
Statement: [Function: Statement],
Backup: [Function: Backup],
OPEN_READONLY: 1,
...
How do I go about accessing the array (i.e. column) of values? Thanks.
Update: here is how I call this fetchItems function in main.js.
const database = require('./database');
ipcMain.on("showItemsButtonClicked", function () {
let itemList = database.fetchItems('food_name');
itemList.then(() => {
mainWindow.webContents.send("itemsRetrieved", itemList);
})
console.log(itemList);
});

I think you are using the wrong syntax.
const fetchItems = (colName) => {
let itemList = database.select(colName).from('food').then((res) => {
// console.log(res);
return res;
}).catch((err) => {
console.log(err)
return [];
})
return itemList
}
Using async await:
const fetchItems = async(colName) => {
try {
let itemList = await database.select(colName).from('food')
return itemList
} catch(err) {
console.log(err)
return [];
}
}

Related

How to show mongoose find() method of an array inside an object

I'm not sure how to explain the following, but I hope I can make myself understood. I am doing a moongose compatible query in NodeJS. That works fine, I do a search and some padding to get the expected result, but there is something I don't understand. I am doing this query through a regEx as I am searching by string parameter. When I do it this way I get something like this:
{
"affiliate": {
"0": {
...content
}
}
}
//The code of the before res using finde in affiliate
export const getAffiliateWithUserName = async (req: Request & any, res: Response, next: NextFunction) => {
try {
const userName: string = req.params.userName;
const affiliate = await Affiliate.find({ "userName": { $regex: userName, $options: "i" } }).populate({
path: "attentionSchedules",
select: "place floor room schedules -affiliate -_id",
populate: { path: "place", select: "name address loc" },
match: { enabled: true }
}).exec();
const affiliateId = affiliate.map(id=> id._id);
const idToString = affiliateId.toString();
const affiliateObjectId = Types.ObjectId(idToString);
const servicesByAff = await ServicesByAffiliate.find({
affiliate: affiliateObjectId,
enabled: true
}).populate("service").populate("category").populate("subCategory").populate("place").populate({
path: "appointmentRequiredService",
populate: { path: "category service" }
}).exec();
console.log(servicesByAff);
const groupedServices = servicesByAff.reduce((acc, serviceByAff) => {
if (serviceByAff.service.isVirtual) {
acc.virtual.push(serviceByAff);
} else if (serviceByAff.service.isDomicilio) {
acc.atHome.push(serviceByAff);
} else {
acc.clinic.push(serviceByAff);
}
return acc;
}, { virtual: [], atHome: [], clinic: [] });
const convertToObject = Object.assign({}, affiliate);
res.status(200).json({
affiliate: { ...convertToObject, groupedServices },
});
// res.json({ affiliate });
} catch (error) {
res.status(500).json({
error: true,
message: error.message,
});
}
};
It's like a nested object, but when I perform my query with findOne passing the schema id as a parameter, the result I get is:
{
"affiliate":{
...content
}
}
//The code use findOne in affiliate
export const groupedServices = async (req: Request & any, res: Response, next: NextFunction) => {
try {
const {affiliateId} = req.params;
const affiliateObjectId = Types.ObjectId(affiliateId);
const affiliate = await Affiliate.findOne(affiliateObjectId).populate({
path: "attentionSchedules",
select: "place floor room schedules -affiliate -_id",
populate: {path: "place", select: "name address loc"},
match: {enabled: true}
}).exec();
const servicesByAff = await ServicesByAffiliate.find({
affiliate: affiliateObjectId,
enabled: true
}).populate("service").populate("category").populate("subCategory").populate("place").populate({
path: "appointmentRequiredService",
populate: {path: "category service"}
}).exec();
console.log(servicesByAff);
const groupedServices = servicesByAff.reduce((acc, serviceByAff) => {
if (serviceByAff.service.isVirtual) {
acc.virtual.push(serviceByAff);
} else if (serviceByAff.service.isDomicilio) {
acc.atHome.push(serviceByAff);
} else {
acc.clinic.push(serviceByAff);
}
return acc;
}, {virtual: [], atHome: [], clinic: []});
res.status(200).json({
affiliate: {...affiliate.toObject(), groupedServices},
});
} catch (e) {
res.status(500).json({
error: true,
message: e.message,
});
}
};
And I need to display my result as the second example, what could it be? Does it have something to do with the way I display my result? Is it some moongose? Could someone give me some recommendation?

how to fix the promise pending in cucumber NodeJS

I'm writing cucumber test and expecting the value true from this function getOutout and doing the assert with the return value but I'm getting the below error:
Error Message:
AssertionError [ERR_ASSERTION]: undefined == true
at processTicksAndRejections (node:internal/process/task_queues:96:5) {
generatedMessage: true,
code: 'ERR_ASSERTION',
actual: undefined,
expected: true,
operator: '==',
[Symbol(originalCallSite)]: [ CallSite {}, CallSite {} ],
[Symbol(mutatedCallSite)]: [ CallSite {}, CallSite {} ]
step.js
const { Given, When, Then } = require('#cucumber/cucumber');
const AWS = require('aws-sdk');
const assert = require('assert');
let isSuccess;
Then('validate the {string} product', function (productType) {
var params = {
stateMachineArn: 'arn:aws:states:us-west-1:121:stateMachine:test',
maxResults: '25',
nextToken: null,
statusFilter: 'SUCCEEDED'
};
const result = getOutout(params).then(function() {
assert.equal(result, true);
})
});
async function getOutout(params) {
const stepfunctions = new AWS.StepFunctions({
region: process.env.AWS_REGION
});
try {
isSuccess = await listExecute(params, stepfunctions);
console.log(isSuccess, 'Output')
} catch (e) {
console.log(e)
}
}
const listExecute = function (params, stepfunctions) {
return new Promise((resolve, reject) => {
stepfunctions.listExecutions(params, function (err, data) {
if (err) reject(err);
else
data.executions.forEach(function (result) {
let params = {
executionArn: result.executionArn
};
stepfunctions.describeExecution(params, function (err, data) {
if (err) reject(err);
else {
resolve(true)
}
});
});
});
})
}
Any help would be much appreciate to fix the issue. Thanks in advance!
not sure why you did this, but it is bad asynchronous code
const result = getOutout(params).then(function() {
})
assert.equal(result, true);
you need to put the assert within the promise callback:
getOutout(params).then(function(result) {
assert.equal(result, true);
})

MongoDB inserting data only if it don't exist (in Javascript)

I'm creating a web scraper and I need to store my data in MongoDB. I scrape some data and store it in a variable call item. I also don't to add a data to the database if it already exist. so here is my resultAnalysis.mjs file that is supposed to do that. What should I change in this code, because it don't insert data and also throw error :
TypeError: Cannot destructure property 'lotNumber' of 'item' as it is undefined.
at file:///Users/AlainMolleyres/Desktop/scraper_V1/resultsAnalysis.mjs:48:11
at runMicrotasks (<anonymous>)
at processTicksAndRejections (internal/process/task_queues.js:93:5)
Here is my code
resultsAnalysis.mjs
mongoose
.connect(mongoURI, { useNewUrlParser: true })
.then(() => console.log("MongoDB connected"))
.catch((err) => console.error(err));
export const compareAndSaveResults = (item) => {
try {
const Schema = mongoose.Schema;
const lotSchema = new Schema({
lotNumber: {},
artistName: {},
artworkNameOriginal: {},
pictureUrl: {},
artworkDate: {},
signed: {},
titled: {},
technic: {},
literature: {},
provenance: {},
dimension: {},
lowEstimation: {},
highEstimation: {},
currency: {},
soldPrice: {},
lotUrl: {},
});
const lot = mongoose.model("lot", lotSchema);
lot
.find({}, function (err, lotList) {
return lotList;
})
.then((lotList) => {
if (lotList == "") {
console.log(`A new data was created:\n${JSON.stringify(item)}`);
const newLot = new lot(item);
return newLot.save().catch((err) => console.log(err));
}
const {
lotNumber,
artistName,
artworkNameOriginal,
pictureUrl,
artworkDate,
signed,
titled,
technic,
literature,
provenance,
lowEstimation,
highEstimation,
currency,
soldPrice,
dimensionInCm,
lotUrl,
} = item;
const dbId = lotList[0]._id;
const dbArtworkNameOriginal = lotList[0].artworkNameOriginal;
const dbLotUrl = newsList[0].lotUrl;
let catchDifference = false;
if (dbArtworkNameOriginal !== artworkNameOriginal) {
catchDifference = true;
} else {
dbLotUrl.forEach((elem, i) => {
if (elem !== lotUrl[i]) catchDifference = true;
});
}
if (catchDifference) {
console.log("A new evidence was found, updating database...");
mongoose.set("useFindAndModify", false);
return News.findOneAndUpdate({ _id: dbId }, item);
}
console.log("File is equal to page, no lot to report");
})
.then(() => {
mongoose.disconnect();
})
.catch((err) => console.log(err));
} catch (err) {
console.error(err);
}
};
``

How to use DataLoader with Mongoose

I'm trying to build the following use case of DataLoader together with Mongoose:
export const PurchaseOrderType = new GraphQLObjectType({
name: "PurchaseOrder",
description: "PurchaseOrder",
interfaces: () => [NodeInterface],
isTypeOf: value => value instanceof PurchaseOrderModel,
fields: () => ({
id: {
type: new GraphQLNonNull(GraphQLID),
resolve: obj => dbIdToNodeId(obj._id, "PurchaseOrder")
},
name: {
type: new GraphQLNonNull(GraphQLString)
},
customer: {
type: CustomerType,
resolve: (source, args, context) => {
return context.customerLoader.load(source.customer_id);
}
}
})
});
export default () => {
return graphqlHTTP((req, res, graphQLParams) => {
return {
schema: schema,
graphiql: true,
pretty: true,
context: {
customerLoader: customerGetByIdsLoader()
},
formatError: error => ({
message: error.message,
locations: error.locations,
stack: error.stack,
path: error.path
})
};
});
};
export const customerGetByIdsLoader = () =>
new DataLoader(ids => {
return customerGetByIds(ids);
});
export const customerGetByIds = async ids => {
let result = await Customer.find({ _id: { $in: ids }, deletedAt: null }).exec();
let rows = ids.map(id => {
let found = result.find(item => {
return item.id.equals(id);
});
return found ? found : null; << === found always undefined
});
return rows;
};
I'm facing the following problems when loading several PurchaseOrders:
A single customer_id is being called more than once in the ids parameter of the DataLoader. So an example id 5cee853eae92f6021f297f45 is being called on several requests to my loader, in successive calls. That suggests that the cache is not working properly.
My found variable when processing the read result is always being set to false, even comparing the right ids.
You can use findOne
export const customerGetByIds = async ids => {
let result = await Customer.find({ _id: { $in: ids }, deletedAt: null }).exec();
const rows = []
let promiseAll = ids.map(async (id) => {
let found = result.filter(item => item.id.toString() === id.toSring());
if(found) {
rows.push(found[0])
return found[0]
}
return null;
});
await Promise.all(promiseAll);
return rows;
};

mongodb : get all users

how do i edit this function of mine to get all users ? I have just started learning async await and i am having hard time learning how to get the request body.
here is my function :
export const get: Operation = async (
req: express.Request,
res: express.Response
) => {
commonUtility.showRequestParam(req);
let users: db.IUserDocument[] = [];
try {
// Describe data acquisition and registration from mongoDB here.
users = await UserModel.find()
.then(data => {
return data;
})
.catch(err => {
throw err;
});
} catch (err) {
// Error.
api.responseError(res, err);
}
if (users.length < 1) {
// this case is 404 ???
api.responseJSON(res, 200, []);
}
};
here is my user model:
export const usersSchema = new Schema({
username: {
type: String,
required: true
},
email: {
type: String,
required: true
},
password: {
type: String,
required: true
},
BaseFields
});
export const UserModel = mongoose.model<db.IUserDocument>('Users', usersSchema);
You don't need to use .then when using async and await
export const get: Operation = async (
req: express.Request,
res: express.Response
) => {
commonUtility.showRequestParam(req);
let users: db.IUserDocument[] = [];
try {
users = await UserModel.find();
api.responseJSON(res, 200,users);
} catch (err) {
// Error.
api.responseError(res, err);
}
};
Read more about async await here -> https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function

Categories