Node js multer send image without update - javascript

friends, I am developing a project with node js, I have a form in my hand, in this form I send pictures and texts to the database (MongoDB), there are no problems with them, including uploading images and updating and sending images.
But the user may want to update and send only the articles, and in this case, he may not want to update the picture. I think about this, I want to send the data to the database without updating the picture, I actually did this, but this time I cannot update the picture while it is in the update process, how can I solve this problem? can you help?
Thank you from now.
The code block I did the update process is as follows
const medicine = await Medicine.findOne({ _id: req.params.id });
medicine.name = req.body.name;
medicine.price = req.body.price;
medicine.medicineType = req.body.medicineType;
medicine.description = req.body.description;
if (req.body.image) {
medicine.image = '/uploads/' + req.file.filename;
} else if (!req.body.image) {
}else{
}
console.log(req.body);
medicine.save();

Related

How can I extract and query data from MongoDB using input from Javascript webpage

I am working on a webpage which takes in input and depending on the user's inputted area code, my program will return data corresponding to this. My database is stored currently using MongoDB and I have attempted to query data using the find function and by connecting to my cluster. Below is the example of a section I have tried (with username and password hideen): Please let me know if anyone can find a solution to this, or if i am connecting this wrong. I am just a student so would appreciate any input.
Thank you!!
This is what i have currently tried, I intially tried to code in Python but this also did not work.
const uri = "mongodb+srv://<username>:<password>#cluster0.mongodb.net/data-police?retryWrites=true&w=majority";
const client = new MongoClient(uri, { useNewUrlParser: true });
client.connect(err => {
const collection = client.db("test").collection("set-1");
// perform actions on the collection object
collection.find({}).toArray(function(err, result) {
console.log(result);
client.close();
});
});

How to upload Bulk amount of json data with images to the firebase realtime and storage respectively

I have a bulk amount of data in CSV format. I am able to upload that data with python by converting them to the dictionary (dict) with loop. the whole data is getting uploaded.
but now I want to upload bulk data to firebase and images to storage and I want to link between each document and image because i am working on e-commerce react app. so that I can retrieve documents along with images.
which is a good way to do this? should I do this with javascript or python?
I uploaded data manually to firebase by importing from there but again I am unable to upload bulk images to storage and also unable to create references between them. please give me a source where I can find this solution
This is tough, because it's hard to fully understand how exactly your images and CSV's are linked, but generally if you need to link something to items stored in Firebase, you can get a link either manually (go into storage, click and item, and the 'Name' Field on the right hand side is a link), or you can get it when you upload it. So for example, I have my images stored in firebase, and a postgres database with a table storing the locations. In my API (Express), when I post the image to blob storage, I create the URL of the item, and post that as an entry in my table, as well as setting it to be the blobs name. I'll put the code here, but obviously it's a completely different architecture to your problem, so i'll try and highlight the important bits (it's also JS, not Python, sorry!):
const uploadFile = async () => {
var filename = "" + v4.v4() + ".png"; //uses the uuid library to create a unique value
const options = {
destination: filename,
resumable: true,
validation: "crc32c",
metadata: {
metadata: {
firebaseStorageDownloadTokens: v4.v4(),
},
},
};
storage
.bucket(bucketName)
.upload(localFilename, options, function (err, file) {});
pg.connect(connectionString, function (err, client, done) {
client.query(
`INSERT INTO table (image_location) VALUES ('${filename}')`, //inserts the filename we set earlier into the postgres table
function (err, result) {
done();
if (err) return console.error(err);
console.log(result.rows.length);
}
);
});
console.log(`${filename} uploaded to ${bucketName}.`);
};
Once you have a reference between the two like this, you can just get the one in the table first, then use that to pull in the other one using the location you have stored.

Firebase Javascript: Creating a numeric Index on File Upload to Firebase Realtime

I've got a little app that allows me to upload files, one at a time, to firebase storage. In the process it creates a database reference where it stores the user that uploaded it, the downlodurl etc.
However I have hit an issue as I want to serve back to the user their uploads at random, which is not something easily done by firebase DB at the moment (it would seem - happy to be proven wrong though!!) so I was wondering if it was possible on upload to create a numeric index field that auto increments after every upload?
Would it be as simple as querying the database pulling the max value for the current index and then +1 to it?
Below is the (fairly boilerplate) database referencing bit of the code where I would want to add the index number:
var imagekey = firebase.database().ref('images/').push().key;
var downloadURL = uploadTask.snapshot.downloadURL;
var updates = {};
var postData = {
url: downloadURL,
index:
user: user.uid
};
updates ['/images/'+imagekey] = postData;
firebase.database().ref().update(updates);
});
Ok thanks to the help of Frank below I was able to write the following function to create a data base reference of "index" and increase it by one on every single upload:
var indexRef = firebase.database().ref('index');
indexRef.transaction(function(currentRank) {
return currentRank + 1;
});
However it did have an incredibly odd effect when inserted into my upload function - the upload would continue to work, the file would appear in storage - but only the index database reference would be written, all other information would be lost and I would get an incredibly complex error in the console. Here is the updated code - any ideas as to what I may have done incorrectly?
function complete(){
//write a database reference
var indexRef = firebase.database().ref('index');
indexRef.transaction(function(currentRank) {
return currentRank + 1;
});
var imagekey = firebase.database().ref('images/').push().key;
var downloadURL = uploadTask.snapshot.downloadURL;
var updates = {};
var postData = {
url: downloadURL,
score: 1500,
index: indexRef,
user: user.uid
};
updates ['/images/'+imagekey] = postData;
firebase.database().ref().update(updates);
});
}
If you want to write a value to the database, based on a value that is currently in the database, you'll use transactions.
The trickiest bit with transactions is that they work on a single location in the database. With the data model you propose, you'd be reading from one post (highest index so far) to then write to another one. That would mean that you need a transaction on the entire images node, which is a huge problem for scalability.
What you'll likely want to do is keep a "highest used counter value" somewhere in a single spot and then "claim next value and write updated value" on that in a transaction. That means read-and-update the counter in a transaction, and then write the image with the index you just claimed.

Firebase JS SDK on 'child_added' not working on large database

I have ~ 1 million users in my users "table" on Firebase.
I need to fetch the username of each user.
once('value' is a way too big of a call, so I try using on 'child_added' but without any success, I am using this code:
usersRef.on('child_added', function (snapshot) {
var user = snapshot.val();
console.log(user);
var username = user.username ? user.username : null;
// Put username in the .txt file, one username per line
});
I waited as much as 15 minute, and nothing happened. It seems to be impossible right now. What could I try besides child_added?
Retrieving one million nodes is very unlikely to ever work. You're simply trying to pull too much data over the network. In that respect there is no difference between value and child_added: both retrieve the same data over the network in the same way.
Limit the number of children you retrieve by a query, either by a query:
var ref = firebase.database().ref("users");
ref.orderByChild("username").equalTo("Dan P.").on("child_added", ...
or by directly accessing the user's node:
var ref = firebase.database().ref("users");
var user = firebase.auth().currentUser;
ref.child(user.uid).on("child_added", ...

associating a GridFS-Stream file to a Schema with Mongoose

I am writing an API for my application, using Mongoose, Express, and GridFS-Stream. I have a Schema for the articles the user will create:
var articleSchema = mongoose.Schema({
title:String,
author:String,
type: String,
images: {type: Schema.Types.ObjectId, ref: "fs.files"},
datePublished: { type: Date, default: Date.now },
content: String
})
var Article = mongoose.model("article", articleSchema, "articles");
and my grid-fs set up for when a user uploads an image:
api.post('/file', fileUpload.single("image"), function(req, res) {
var path = req.file.path;
var gridWriteStream = gfs.createWriteStream(path)
.on('close',function(){
//remove file on close of mongo connection
setTimeout(function(){
fs.unlink(req.file.path);
},1000);
})
var readStream = fs.createReadStream(path)
.on('end',function(){
res.status(200).json({"id":readStream.id});
console.log(readStream);
})
.on('error',function(){
res.status(500).send("Something went wrong. :(");
})
.pipe(gridWriteStream)
});
Right now it's set up to when the user chooses an image, it automatically uploads it via gridfs-stream, puts it in a temp folder, then deletes it when it is uploaded to the mongo server, and in the console returns what the ObjectId is. Well thats all find and dandy, but we need to associate this ID with the articleSchema, so when we call that article in the app, it will display the associated image.
on our creation/update of an article when the user hits submit:
createArticle(event) {
event.preventDefault();
var article = {
type: this.refs.type.getValue(),
author: this.refs.author.getValue(),
title: this.refs.title.getValue(),
content: this.refs.pm.getContent('html')
};
var image = {
images: this.refs.imageUpload.state.imageString
};
var id = {_id: this.refs.id.getValue()};
var payload = _.merge(id, article, image);
var newPayload = _.merge(article, image)
if(this.props.params.id){
superagent.put("http://"+this.context.config.API_SERVER+"/api/v1.0/article/").send(payload).end((err, res) => {
err ? console.log(err) : console.log(res);
});
} else {
superagent.post("http://"+this.context.config.API_SERVER+"/api/v1.0/article").send(newPayload).end((err, res) => {
err ? console.log(err) : console.log(res);
this.replaceState(this.getInitialState())
this.refs.articleForm.reset();
});
}
},
So what I need it to do, is call the ID, of the image I just uploaded to the images section of my schema when the user hits submit on the creation of an article. I've tried doing a readstream on submit, but again, the problem is I can't get the ID, or the filename, to be able to associate it.
They are getting stored in the mongo database, it creates fs.files and fs.chunks, but for the life of me I can't figure out how to get that data and attach it to a schema, or just even get the data out, without knowing the ObjectId.
So how do I call out the objectid from fs.files or fs.chunks to attach it to the schema? and in the schema how do I reference the fs.files or chunks? so it knows what the objectid is associated with?
I can provide anymore data, if what I have is to vague, I have a nasty habit of doing that. sorry.
So I ended up solving my problem, might not be the best solution, but it works until I can get a better solution.
in the API changed
res.status(200).json({"id":readStream.id});
to
res.status(200).send(readStream.id);
in my component, I then set the state to the response.body, which will set the state of the id of the image uploaded. So in the main view, i reference the image uploading component, and set the image state of my view to the id state of my component, and viola, I now have the id in my database, associated with the newly created article.
the problem i then ran into was, it didn't know what to reference. so I attached the API URL to the id, and it acts like it is referencing a URL img, and renders the image correctly.
Again, this may not be the best way to go about this, in fact, I am pretty sure it isn't, but It is whats working for now until I can either reference the database correctly, or create a new component that just stores all the images on server and reference them that way, much like wordpress.

Categories