Very new to express and mongodb with gridfs-stream - image

and thanks in advance for any help you guys can give me. I am trying to use mongodb, mongoose, gridfs-strea, and express to store img files on mongodb.
I do not want to store the file in a folder. I want gfs.createWriteStream to take the file directly from app.post from express. App.post is currently saving some strings through a schema model into mongodb.
The form that routes to app.post contains strings and a input for img file.
I tried to do this(dnimgfront being the name of the input):
dnimgfront:req.pipe(gfs.createWriteStream('req.body.dnimgfront'))
I am getting back.
TypeError: Object function Grid(db, mongo) {
if (!(this instanceof Grid)) {
return new Grid(db, mongo);
}
mongo || (mongo = Grid.mongo ? Grid.mongo : undefined);
My problem is I have to be able to store the img and the strings from the same app.post save function. Any ideas?
What I'm using to connect to mongodb is:
mongoose.connect('mongodb://localhost/veeltaxi');
var con=mongoose.connection;
con.once('open', function(){
console.log('connected to mongodb succesfully!')
});
Thanks in advance for your help.

First, you need an instead of gridfs-stream:
var GridStream = require('gridfs-stream');
var mongodb = require('mongodb');
var gfs = new GridStream(mongoose.connection,mongodb);
At which point you can create the write stream and pipe:
var writeStream = gfs.createWriteStream({
filename: filename, // the name of the file
content_type: mimetype, // somehow get mimetype from request,
mode: 'w' // ovewrite
});
req.pipe(writeStream);
However, at this time the Node.js MongoDB Driver is at version 2.0 which uses Streams 2, so there is no reason to use gridfs-stream if you're using that version of the mongodb lib. See the source code for v2.0.13. FYI, the stream that is implemented in the updated driver is Duplex. (Aside: gridfs-stream has its share of problems, and while actively maintained, is not very frequent.)

Related

How to write data in a file without replacing the existing data using cy.writeFile

I'm trying to save some data from API in a .json file using cy.writeFile method, but my code is replacing the existing data.
What I need is to add additional data.
cy.intercept('POST', 'http://viasphere.localhost/sites/datatable').as('response')
cy.contains('Sortir').click()
cy.wait('#response').get('#response').then(xhr => {
console.log(xhr)
let siteID = xhr.response.body.data[0].id
let creationDate = xhr.response.body.data[0].created_at
let RM = xhr.response.body.data[0].metal_rollout
let clientGroup = xhr.response.body.data[0].client_contact_group
cy.writeFile('SiteAPIdata.json', {siteID2: siteID})
After the run, the data existing inside the SiteAPIdata.json file is being replaced by the new data.
The SiteAPIdata.json file is located in cypress/fixtures/ folder.
Thank you!
Assuming you want to append the new data to the existing data, that can easily be accomplished by using cy.readFile() before writing.
...
cy.readFile('SiteAPIdata.json').then((data) => {
data.siteID = siteID;
cy.writeFile('SiteAPIdata.json', data);
})

How to add data to IndexedDb in service worker which are coming as http response from api

I have a application in codeigniter and angular framework. All its data are coming from api's that are we have created in codeigniter . Now i am trying make this application a pwa . so far,caching of static file and manifes.json are working ,but when it comes to storing those data in IndexedDb and retriving them i am confused how to that.Till now i have find only examples with static json being inserted into IndexedDb ,but i want to know how to store those http response in indexedDb, so that when it goes in offline mode it automatically provide data.Also in every page have more than one http response is coming so it should also provide right data to variables..
If you any part of question than just let me know ,I will try better to explain.
And thank you all in advance.
If the response from api is JSON or some similar sort of data file then you can store in indexDB as string or manipulate as you need.Here's an example of storing JSON as string.
//JSONfile is the response from your api.
var JSONstring = JSON.stringify(JSONfile)
// Storing JSON as string in indexDB
var dbPromise = idb.open('JSON-db', 1, function (upgradeDB) {
var keyValStore = upgradeDB.createObjectStore('JSONs')
keyValStore.put(JSONstring, 'samples')
})
//provide better key name so that you can retrieve it easily from indexDB
Other case if response is some sort of multimedia then you can convert it into blob and then store the blob in indexDB.
return fetch(new Request(prefetchThisUrl, { mode: 'no-cors' }))
.then((resp) => {
resp.blob()
.then((blob) => {
return db.set(prefetchThisUrl, blob);
});
});
You can then get the information from indexDB when required.For a good understanding of storing and retrieving blob from indexDB you can visit this site:https://hacks.mozilla.org/2012/02/storing-images-and-files-in-indexeddb/
And for providing right data on your page it's not an issue,you just need to make your logic to respond to request from indexDB.Here's how you can do it.
dbPromise.then(function (db) {
var tx = db.transaction('JSONs')
var keyValStore = tx.objectStore('JSONs')
return keyValStore.get('samples')
}).then(function (val) {
var JSONobject = JSON.parse(val)}

Convert Document.getFileAsync data to FormData for Office file uploading

I'm working on Office Add-in project, I need to get current Office file and upload to our server.
Below is upload file from File Browser to our server
var fdata = new FormData();
fdata.append('data', file);
fdata.append('totalFileSizeBytes', file.size);
fdata.boundary = '----boundary';
xhr.send(fdata);
And I got Office file info via function: Document.getFileAsync (https://dev.office.com/reference/add-ins/shared/document.getfileasync)
But I don't know how to convert File info from Document.getFileAsync to FormData.
I tried read File info slice by slice then concat to an array and pass to FormData, but it wasn't success.
The answer is a bit late, but hopefully might help future folks looking for this - I wasted some time trying to figure this out.
The File object returned by the Document.getFileAsync is not usable with FormData. Also what the Microsoft Documentation shows you does not get you a file that you can just drop into FormData.
First, you'll have to combine the slices returned to a docdata array as per the Microsoft example shows (https://learn.microsoft.com/en-us/javascript/api/office/office.document?view=office-js#getfileasync-filetype--options--callback-). But then instead of creating a string out of it by using charCodeAt, you'll want just use the combined docdata array and do this:
const file = new File(
[new Uint8Array(docdata)],
'testfile.docx',
{ type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' }
);
Which you can then proceed to append to your FormData:
const fd = new FormData();
fd.append('file', file);
The new File() gave me an error. But the a new Blob() did the trick
var aFile = new Blob(
[new Uint8Array(docdata)],
{ type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' }
);
formData.append('file', aFile, 'testfile.docx');

Cordova/Phonegap How to write a PNG file to Filesystem?

This question goes for mp3 and wav files as well.
I have set up an express.js server which basically sends the required files as follows:
res.sendFile('someImage.png', {root: './images'});
Then on the client-side, I receive the image with:
var req = new XMLHttpRequest();
...
req.onreadystatechange = function(e) {
if(req.readyState != 4) return;
...
writeMyFile(null, e.target.response, someCallback);
}
...
So in the response I do have my file. I want to write this file in to my local filesystem. I implement write as follows:
var writeMyFile = function(err, file, someCallback) {
this.dir.getFile('myImages/someImage.png', {create: true}, function(fileEntry) {
fileEntry.createWriter(function(fileWriter) {
var blob = new Blob([file], {type: 'image/png'});
fileWriter.write(blob);
}, someCallback);
}, someCallback);
};
After executing these, I see a png file is created in myImages folder. It is however twice the size of the original file, and it is considered as corrupted by the operating system. Preview cannot view the image. Same goes for mp3/wav files as well, they are twice the size and won't play on any players and etc..
What am I doing wrong here? How can I write those files into filesystem appropiately?
The code above works perfectly when files are json objects. We suspect there might be an encoding problem, but no idea for fixes so far.
Finally, I am using the closure compiler.
Thanks for your help.
After sleeping on the problem, I found out the solution which was incredibly simple. So here it is for future reference.
On Xhr Request, make sure to set the responseType to arrayBuffer or blob before sending the request. In my case it is arrayBuffer because I already had a blob builder which would act on the data received. That is:
...
req.responseType = 'arraybuffer';
req.onreadystatechange = ...
req.send();
It turns out that Mime Type in blob construction won't affect these binary files to be written. In my case, I could store mp3 songs perfectly where I had their MIME as: 'image/png'. However I am not sure if this has other implications, I am just simply saying that the files worked ok no matter which type I had set.

Issue Retrieving a Screenshot from a database

I've got a bunch of screenshots and some screenshot meta data I'm trying to display in an ASP.NET MVC 3 web application, I'm trying to retrieve the data from my databse but I get this error:
LINQ to Entities does not recognize the method 'System.Drawing.Image
ByteArrayToImage(Byte[])' method, and this method cannot be translated
into a store expression.
Here's my code:
var screenshotData = (from screenshots in db.screenshots
where screenshots.projects_ID == projectID
select new ImageInformation
{
ID = screenshots.id,
Language = screenshots.language,
Screenshot = Utility.ByteArrayToImage(screenshots.screen_shot),
ProjectID = screenshots.projects_ID
});
foreach (ImageInformation info in screenshotData)
{
this.Add(info);
}
ImageInformation is just a simple class that contains the defintion the information stored (ID, Language, Screenshot, ProjectID).
Here's my ByteArrayToImage function:
public static Image ByteArrayToImage(byte[] byteArrayIn)
{
using (MemoryStream ms = new MemoryStream(byteArrayIn))
{
Image returnImage = Image.FromStream(ms);
return returnImage;
}
}
Can anybody tell me why I receive this error when this code runs?
Thanks.
I think it's because, with LINQ-to-Entities, the code is turned into server-side query and it can't do that in this case. I don't think you can mix client-side code like this directly with L2E.
I would suspect you will have to do the conversion from byte->image after you've retrieved the data from the database as a distinct step.
You can't do the function in a LINQ to Entities query... one option:
1) have a byte[] property on the object you are instantiating (ImageInformation) and copy the data in there along with another propery to read the image from this ImageInformation object.

Resources