How to create new record through JSON Data - node.js

Here, I have some difficulty to how to create new record whenever i have create one csv file and upload it,
then now how can i create new record throgh this,
please help me.!
This is my Csv file.
name,companyId,engineId,colorId
car1,123,123,123
car2,456,456,456
uploadAvatar: function (req, res) {
let fileInputName = 'assets/excel/carData.csv';
let fileOutputName = 'myOutputFile.json';
req.file('excel').upload({
// don't allow the total upload size to exceed ~10MB
dirname: require('path').resolve(sails.config.appPath, './assets/excel'),
saveAs: 'carData.csv',
maxBytes: 10000000
}, function whenDone(err, uploadedFiles) {
if (err) {
return res.serverError(err);
}
// If no files were uploaded, respond with an error.
if (uploadedFiles.length === 0) {
return res.badRequest('No file was uploaded');
}
csvToJson.generateJsonFileFromCsv(fileInputName, fileOutputName);
csvToJson.fieldDelimiter(',') .getJsonFromCsv(fileInputName);
let json = csvToJson.getJsonFromCsv("assets/excel/carData.csv");
csvToJson.formatValueByType().getJsonFromCsv(fileInputName);
//var result = [];
var name = "";
var comapanyId = "";
var engineId = "";
var colorId = "";
for (let i = 0; i < json.length; i++) {
console.log(json[i]);
**// How to create new record ?**
}
return res.json({
message: uploadedFiles.length + ' file(s) uploaded successfully!',
});
});
},
This is my model file
module.exports = {
tableName: 'Car',
schema: true,
attributes: {
name: {
type: 'STRING'
},
companyId: {
model: 'Master',
columnName: 'companyId'
},
engineId: {
model: 'Master',
columnName: 'engineId'
},
colorId: {
model: 'Master',
columnName: 'colorId'
},
car: {
collection: 'Order',
via: 'carId'
},
},
};

You have to call the .createEach([cars]) method.

Related

Submitting without files resets the all images in the array when making a PATCH request

I'm trying to make a dynamic field for adding team members using Formik.
In my backend, if I do not choose any file and edit only other field such as "memberName" I'm getting message saying;
"Cast to embedded failed for value "{
_id: '63c5687832a80d5d8f717715',
memberName: 'qqaa',
memberJobTitle: 'qq',
memberDescription: 'qq',
images: [ 'undefined' ]
}" (type Object) at path "team" because of "CastError""
I want to keep the existing images if there is no changes in the input field. I'm having this issue for a week and couldn't figure it out.
This is my controller for making a PATCH request;
const updateSection = async (req, res, next) => {
const files = req.files;
const {
pageId,
welcomeTitle,
welcomeDescription,
aboutUsTitle,
aboutUsDescription,
team,
teamTitle,
} = req.body;
let updates = {};
//update other fields if they are provided in the request body
if (welcomeTitle) {
updates.welcomeTitle = welcomeTitle;
}
if (welcomeDescription) {
updates.welcomeDescription = welcomeDescription;
}
if (aboutUsTitle) {
updates.aboutUsTitle = aboutUsTitle;
}
if (aboutUsDescription) {
updates.aboutUsDescription = aboutUsDescription;
}
if (teamTitle) {
updates.teamTitle = teamTitle;
}
if (team) {
let teamPromises = []; //create an empty array to store promises for updating or creating team members
// updates.team.images = [];
team.forEach((item, i) => {
// item -> current team member being processed, i-> index in the array
let teamMember = {
_id: item._id,
memberName: item.memberName,
memberJobTitle: item.memberJobTitle,
memberDescription: item.memberDescription,
images: item.images,
};
if (files && files[i]) {
let file = files[i];
let img = fs.readFileSync(file.path);
let decode_image = img.toString("base64");
teamMember.images = [
{
filename: file.originalname,
contentType: file.mimetype,
imageBase64: decode_image,
},
];
} else {
teamMember.images = item.images;
}
teamPromises.push(
Section.updateOne(
{ pageId: pageId, "team._id": item._id },
{ $set: { "team.$": teamMember } },
{ new: false }
)
);
});
Promise.all(teamPromises)
.then((result) => {
res.status(200).json({ message: "Section updated successfully!" });
})
.catch((error) => {
res.status(500).json({ error: error.message });
});
} else {
//update other fields if no team member provided
Section.findOneAndUpdate({ pageId: pageId }, updates).then(() => {
res.status(200).json({ message: "Section updated successfully!" });
});
}
};

Adding link to Mongo DB when uploading image to AWS S3 Bucket

In my Express backend, I have set up a connection with S3 Bucket for uploading images, and it works.
However additionally, I would like to be able to store a reference link (S3 url) of the saved image in my Mongo Database.
I have been trying to play around with req.file object but somehow, I cannot get the req.file.location, whereas req.file.buffer works okay (as in the example below in itemController.js). Is there any problem in my s3.js configuration? Or pehraps I would need a different approach to get req.file.location instead of buffer?
Below my bucket configuration s3.js
// s3.js
const AWS = require('aws-sdk')
// s3 bucket configuration
const awsConfig = {
accessKeyid : process.env.S3_ACCESS_KEY,
secretAccessKey : process.env.S3_ACCESS_SECRET,
region : process.env.S3_REGION
}
const S3 = new AWS.S3(awsConfig)
//s3 bucket upload function
const uploadToS3 = (fileData) => {
return new Promise ((resolve, reject) =>{
const params = {
Bucket : process.env.S3_BUCKET_NAME,
Key: `${Date.now().toString()}.jpg`,
Body: fileData
}
S3.upload(params, (err, data) =>{
if(err){
console.log(err)
reject(err)
}
console.log(data)
return resolve(data)
})
})
}
module.exports = {
uploadToS3
}
Here is my itemController.js
const Item = require('../models/itemModel')
const Worker = require('../models/workerModel')
const mongoose = require('mongoose')
const multer = require('multer')
const { uploadToS3 } = require('../s3')
//! Multer configuration
const multerConfig = {
limits: 1024 * 1024 * 5,
fileFilter: function (req, file, done) {
if (file.mimetype === "image/jpg"|| file.mimetype === "image/png" || file.mimetype ==='image/jpeg') {
done(null, true)
} else {
done("Niewłaściwy plik, użyj .jpg .jpeg .png", false)
}
}
}
const upload = multer(multerConfig)
//! CREATE new item
const createItem = async (req, res) => {
// multer middleware that handles file upload
upload.single("image")(req, res, async () => {
//destructuring form req.body
const {
title,
model,
producer,
serialNumber,
yearOfProduction,
atEmployee,
seller,
warrantyDate,
purchaseDate,
image,
} = req.body
if (!title){
return res.status(400).json({error:'Błąd! Wymagane jest podanie chociaż nazwy narzędzia.'})
}
//try-catch to create new Item and catch error. Add "await" because of "async" - Js promise above
try {
const item = await Item.create({
title,
model,
producer,
serialNumber,
yearOfProduction,
atEmployee,
seller,
warrantyDate,
purchaseDate,
image: req.file ? req.file.buffer : image,
})
if (req.file) {
// upload file to S3 and store the URL in the database
const result = await uploadToS3(req.file.buffer)
item.imageUrl = result.location
await item.save()
}
res.status(200).json(item)
} catch(error) {
res.status(400).json({error: error.message})
}
})
}
...
And here is my ItemModel.js
const mongoose = require('mongoose')
//mongoose function to create new model Schema
const Schema = mongoose.Schema
const itemSchema = new Schema ({
title: {
type: String,
required: true,
},
producer: {
type: String,
required: false,
},
model: {
type: String,
required: false,
},
serialNumber: {
type: String,
required: false,
},
yearOfProduction:{
type: Number,
required: false
},
seller:{
type: String,
required: false
},
purchaseDate: {
type: Date,
default: Date.now
},
warrantyDate: {
type: Date,
required: false,
},
//Linking Worker model to an Item
atEmployee: {
type: mongoose.Schema.Types.ObjectId,
required: false,
ref:'Worker',
},
image: {
type: String,
required: false,
}
}, { timestamps: true })
module.exports = mongoose.model('Item', itemSchema)
This is how I actually solved it
itemController.js
const Item = require('../models/itemModel')
const Worker = require('../models/workerModel')
const mongoose = require('mongoose')
const multer = require('multer')
const { uploadToS3 } = require('../s3')
//! Multer configuration
const multerConfig = {
limits: 1024 * 1024 * 5,
fileFilter: function (req, file, done) {
if (file.mimetype === "image/jpg"|| file.mimetype === "image/png" || file.mimetype ==='image/jpeg') {
done(null, true)
} else {
done("Niewłaściwy plik, użyj .jpg .jpeg .png", false)
}
}
}
const upload = multer(multerConfig)
//! CREATE new item
const createItem = async (req, res) => {
// multer middleware that handles file upload
upload.single("image")(req, res, async () => {
//destructuring form req.body
const {
title,
model,
producer,
serialNumber,
yearOfProduction,
atEmployee,
seller,
warrantyDate,
purchaseDate,
image,
} = req.body
if (!title){
return res.status(400).json({error:'Błąd! Wymagane jest podanie chociaż nazwy narzędzia.'})
}
//try-catch to create new Item and catch error. Add "await" because of "async" - Js promise above
try {
let item = {}
if (req.file) {
// upload file to S3 and store the URL in the database if image has been uploaded
const result = await uploadToS3(req.file.buffer)
item = await Item.create({
title,
model,
producer,
serialNumber,
yearOfProduction,
atEmployee,
seller,
warrantyDate,
purchaseDate,
image: result.Location,
})
//if no image, show nothing
} else {
item = await Item.create({
title,
model,
producer,
serialNumber,
yearOfProduction,
atEmployee,
seller,
warrantyDate,
purchaseDate,
})
}
res.status(200).json(item)
} catch(error) {
res.status(400).json({error: error.message})
}
})
}

importing a sample excel sheet from database postgresql

I want to import an excel sheet from a database containing state list with a foreign key of countries.
What I want to do is the column for the country to become a dropdown list so that I could enter the state name with the reference country name selected from the country dropdown:
const getStateSampleFile = async (req, res) => {
try {
const countryData = await Countries.findAll({
where: { deleted: false },
});
const workbook = new excelJS.Workbook();
const workSheet = workbook.addWorksheet('StateData');
workSheet.columns = [
// { header: 'S.no', key: 's_no', width: 20 },
{ header: 'Countries', key: 'Countries', width: 20 },
{ header: 'States', key: 'state', width: 20 },
];
// let count = 1;
countryData.forEach((country) => {
// country.s_no = count;
country.Countries = country.name;
// workSheet.addRow(country);
// count += 1;
// return dropList.push({ dlist });
return country.name;
// console.log(dlist,'98989')
// return country.name;
});
// console.log(dlist, '909099090');
workSheet.getCell('A1').dataValidation = {
type: 'list',
allowBlank: true,
formulae: [],
};
workSheet.getRow(1).eachCell((cell) => {
cell.font = { bold: true };
});
const filename = `States${Date.now()}.xlsx`;
res.setHeader('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
res.setHeader('Content-Disposition', `attachment; filename=${filename}`);
await workbook.xlsx.writeFile('statesampledata.xlsx');
res.send('done');
return workbook.xlsx.write(res).then(() => {
res.status(200).end();
});
} catch (error) {
throw new Error(error);
}
};

Casting error while saving in the database

I am using Angular as frontend and NodeJS for the backend.
I have a route that saves the data received from the frontend to the database. When I execute the save() method, I get prompted the following error:
err : ValidationError: conf.0: Cast to [Boolean] failed for value "[ {
name: 'v', percentage: 2, type: false, status: true } ]" (type string)
at path "conf.0"
Below is the route that stores the data:
app.post("/api/submitTaxCollection", (req, res) => {
console.log(req.body);
const submitTaxSchema = new addTaxesSchema(req.body);
try {
submitTaxSchema.save(function (err) {
if (err) return console.log("err : " + err);
});
} catch (error) {
console.log("ERROR : " + error);
return res.send(error);
}
});
and this is the schema.ts file:
var mongoose = require("mongoose");
//Define a schema
var taxSchema = mongoose.Schema;
var AddTaxSchema = new taxSchema({
parentId: String,
conf: [
{
name: String,
percentage: Number,
type: Boolean,
status: Boolean,
},
],
});
var newTaxesSchema = mongoose.model("addTaxSchema", AddTaxSchema);
module.exports = newTaxesSchema;
In Angular, model is setup as below:
export class TaxRatesConfigurationsModel {
name: string = "";
percentage: number = 0;
type: boolean = false;
status: boolean = true;
}
export class TaxRatesModel {
parentId: string = "";
conf: TaxRatesConfigurationsModel[] = [];
}
and I am calling the API as below:
this._httpService
.post(environment.url + "/api/submitTaxCollection", request)
.subscribe((data) => {
console.log(data);
});
when I console.log(req.body);, I get the following printed to the console (Nodejs):
{
parentId: '23948923nur8cw9yicnyu',
conf: [ { name: 'v', percentage: 2, type: false, status: true } ]
}
and the error occurs in Nodejs
What is causing this weird issue?

How to save base64 encoded file in LoopBack within a hook

I'm trying to find a way to save a file in a loopback application that was send as base64 encoded string.
So I have a model with all possible field and also a base64 encoded image, “receipt”.
{
...modelData,
"receipt": "datadata:image/jpeg;base64,whatever=="
}
So... what I'm thinking of is this
Model.beforeRemote('create', function(ctx, model, next) {
const file = ctx.args.data.receipt;
app.models.Attachment.upload(...)
// and replace base64 with returned filename
})
But I don't clearly understand how and what should I pass to that upload method. Or maybe it has to be some different approach.
Thanks!
This isn't really a remote hook but rather a remote method, yet I believe you can adapt the code to your own needs.
We basically create a remote method called "upload" for Documents model and it takes care of uploading it to a predefined container name.
const CONTAINERS_URL = '/api/container/';
const fs = require('fs');
const path = require('path');
const encodedFileContainer = 'files';
module.exports = function(Document) {
Document.upload = function(encodedFile, fileName, cb) {
let uploadStream = Document.app.models.container.uploadStream(
encodedFileContainer,
fileName
);
uploadStream.end(encodedFile, 'base64', async err => {
if (err) return cb(err);
let newRecord = await Document.create(
{
fileName,
url: CONTAINERS_URL + encodedFileContainer + '/download/' + fileName,
container: encodedFileContainer
},
function(err, obj) {
if (err !== null) {
cb(err);
} else {
cb(null, obj);
}
}
);
});
};
Document.remoteMethod('upload', {
description: 'Uploads a file',
accepts: [
{
arg: 'endcodedFile',
type: 'string',
required: true,
description: 'base64 encoded file',
http: {source: 'form'}
},
{
arg: 'fileName',
type: 'string',
required: true,
description: 'file name',
http: {source: 'form'}
}
],
returns: {
arg: 'fileObject',
type: 'object',
root: true
},
http: {verb: 'post'}
});

Resources