I am new to nodejs. I am basically using express, and I have to create a form to upload photos. So far I have created a file called upload.handlebars where I have written the following code:
<form enctype="multipart/form-data" action="uploads" method="post">
<input type="file", id = "image", name="image", accept="image/*">
<input type='submit' id='tags' value='Upload'>
I have another file called router.js where I have written the post function. One of the lines in the post function is:
fs.readFile(req.files.image.path, function (err, data) {
However, I get an error as follows:
TypeError: Cannot read property 'image' of undefined at Object.handle....
How should I specify the 'name' of the image file in my router.js?
Make sure you have multiparty middleware enabled.
https://github.com/andrewrk/connect-multiparty
Latest express doesn't come with it.
you can use express to solve this problem quickly. to know more read the folowing page express api reference
for now the following code may help you -
app.post('<your path>',express.bodyParser(),function(req,res){
console.log(req.files);//to get all the files uplaoded
});
make sure express version should 3.4
Related
I'm currently trying to make the user can edit their profile picture, I'm using nodejs, react & multer for that. On the other hand I receive an error when I send my form, I show you my code I hope you can help me.
Sending the form gives me no error when I put a req.body.file in my edit function but then the image of my profile is undefined,
I also tried req.file[0].filename, which doesn't work either.
I would like that when the user uploads an image it is downloaded in my images folder and that it is also displayed on the user's profile
I thank you in advance
when doing a put request you are sending your data in JSON not in form data. you need to do something like this
const onSubmit = () => {
const formData = new FormData();
formData.append("firstName", firstName);
....
formData.append("avatar", avatar);
also FileReader.readAsDataURL return string but multer needs value of type File, so we need to directly store event.target.files[0] inside state so that multer can read it.
make sure you have express middleware
app.use(express.json());
not but the least upload.single("avatar") it should be the name of variable
hope these changes help you.
I didn't see your implementation for React updateUser, but looks like you are using the key avatar when uploading a file but accessing it via image key.
Also just use file Blob from HTMLInput
const handleImgUpload = (e) => setAvatar(e.target.files[0])
Try to change your router to
router.put('/update/:id', requiresAuth, upload.single('avatar'), updateUser)
and make sure you submit the form with Content-Type header multipart/form-data
I'm trying to port the following code from Ruby with the selenium-webdriver gem to Node.js with WebdriverIO:
#webdriver.navigate.to "https://imgur.com/upload"
element = #webdriver.find_element(:id, 'global-files-button')
element.send_keys("C:\\test\\image.png")
As you can see the code is very simple: navigate to a url, find the input, set the file path and it works as expected selecting the file for upload.
This is my ported version:
describe('User can upload', () => {
it('select file', () => {
browser.url("https://imgur.com/upload");
browser.waitForExist('#global-files-button');
$('#global-files-button').keys("C : \\ t e s t \\ i m a g e . p n g".split(" "));
});
});
Unfortunately this test doesn't set the path and I haven't been able to find a working example of uploading a file like this with wdio and the documentation has left me guessing. Any suggestions much appreciated.
I'm aware of both chooseFile and uploadFile but I'm working with a cloud platform to run my wdio tests and they don't seem to work reliably.
I've had trouble with this. From what I've researched it is not an issue with WebdriverIO or it's chooseFile() or uploadFile() methods. The root of the issue I believe comes down to an error in Selenium Webdriver being unable to handle the 'multiple' <input type='file' multiple> upload elements.
I fought this for a solid maybe 3 days before stumbling across this github issue:
https://github.com/SeleniumHQ/selenium-google-code-issue-archive/issues/2239
Long story short, because the HTML on imgur has the "multiple" property on it, your upload tests won't work correctly. WebdriverIO / Selenium just stops functioning from what I've noticed.
Note: I've been able to actually have my application upload a single file and add files to my system and application while testing an <input type='file' multiple>. The problem is however, that WebdriverIO and Selenium just stops. The tests end, without reporting any success or failure results.
If you go and test another <input type=file> element somewhere across the web that is NOT designated as a "multiple" upload input field you should be able to make the chooseFile() methods from WebdriverIO function correctly.
I hope this helps you and perhaps anyone else who's struggled with file uploads.
EDIT:
I've tried to make your example work, and I had success with "chooseFile()" and passing the "filepath" to it directly. Perhaps you're trying to send keyboard commands when you don't really have to? Do you have a direct file path to the image you're attempting to upload? Below is what i was able to use to successfully upload a file.
it('upload a file to imgur', function () {
browser.url("https://imgur.com/upload");
browser.waitForExist('#global-files-button');
browser.chooseFile('#global-files-button', '/insert/path/to/image.png')
})
// c:/test/image.png
var test1 = 'c:/test/image.png'
var path = test1.split('/').join('\\\\')
browser.addValue('[name="fileField"]', path )
or maybe this also work
// c:\test\image.png
var path = 'c:\\test\\image.png'
browser.addValue('[name="fileField"]', path )
or maybe this
// c:/test/image.png
var path = 'c:/test/image.png'
browser.addValue('[name="fileField"]', path )
Hi I need to automate a website using cucumberJS and webdriverIO. For that I need to Upload a file but the field is hidden. For Example :
<input type="file" id='uploadFile' style="display: none"'>
but webdriver is unable to identify the element on the UI.
Thanks in Advance...
In webdriverIO v5, files are uploaded to inputs of type="file" by calling .setValue() on them with the local file path as an argument. This doesn't seem to work for hidden inputs though, because .setValue() first calls .clearValue() which will throw Element could not be scrolled into view. To work around this, call .addValue() directly on the element:
input.addValue(filePath);
Relevant API docs: https://webdriver.io/docs/api/element/addValue.html
I got the solution for this Issue.Using webdriverIO we can execute javascript to change the style display from "none" to "block".
client.execute(function() {
document.getElementById("element_id").style.display="block";
},function(err) {
client.uploadFile(localPath[,callback])
if(err){
console.log("Error "+err);
}
});
then upload the file to the field and then change the display again to none.
I'm working with polymer and I'm testing all in my local environment and all is working as expected, but the problem is when I'll move it into production, where the url shouldn't be the same as in my local. In node.js I can set it via the config.json file and catch it with app.get('config') or something like that, but in polymer I cant get it, and the only chance I have is to create another endpoint with all the config.json config file, but, and here is the best part, I should hardcode this url in polymer!! (so annoying). There is some way or library or component or something that I'm missing ?
Thanks in advance guys! StackOverflow and the users helped my a lot!
UPDATE
The thing is that I'm using custom elements (because I had handlebars too and there is a little problem with the {{}}) so, in the custom elements that I created I have this (for example in the core-ajax call):
<core-ajax id="login" auto="false" method="POST" contentType="application/json" url="/app/middle/login" ....></core-ajax>
as you can see the url is a little bit hardcoded, I want to use something like this (this is what I have on the node.js endpoint application):
router.post(endpoint.login, function (req, res) {
and I want to got something like that over polymer
<core-ajax id="login" auto="false" method="POST" contentType="application/json" url="{{login}}" ... ></core-ajax>
<script>
Polymer('log-form', {
login: endpoint.login,
ready: function () {
....
})
});
</script>
I'ts more clear now? I'm not so strong on english language.
Thanks Guys, for all!
Multiple files are being posted to nodejs application using Express and bodyParser.
The number of files change in every request. It is required to get number of files posted at the server.
I have tried using
req.files.length
but it gives undefined. How can I know the number of files posted in a post request?
Also how to loop through each file?
Putting answer my self.
It should be iterated upon like this
for (x in files){
//code for handling each object in json.
}
You can get the length of and iterate a collection of files with the name of the <input>:
// example: <input type="file" name="images" multiple>
req.files.images.length;
req.files.images.forEach(function (file, i) {
// ...
});
You can find an example of this in the Connect repository: examples/upload.js