File upload (s3) with text values


#1

I’m trying to add a file upload to one of my forms to stream the file to the database, get the URL back from s3 and save it to the database with the regular text inputs, but I’m having some trouble and I think its related to enctype="multipart/form-data"

My form:

<form method='POST' action="{{ route('storePartner') }}"enctype="multipart/form-data">
{{csrfField()}}

    <div class='c-media__content'>
      <label> {{antl.formatMessage('partners.partner')}} </label>
      <input type='text' class='form-control' value="{{ old('name', '') }}" placeholder='{{antl.formatMessage('partners.name')}}' name='name'>
      
      <label> {{antl.formatMessage('partners.web')}} </label>
      <input type='text' class='form-control' value="{{ old('website', '') }}" placeholder='{{antl.formatMessage('partners.url')}}' name='website'>
      
      <label for="">Logo</label>
      <input type="file" name="logo" class="form-control">
      <label> {{antl.formatMessage('partners.description')}} </label>
      <textarea rows='10' cols='50' type='text' value="{{ old('description', '') }}" class='form-control form-control__area' name='description' placeholder='{{antl.formatMessage('partners.desc')}}'></textarea>
      
      <label> {{antl.formatMessage('partners.visibility')}} </label>
      <select name='display' class='form-control col-sm-2   '>
        <option value='T'> {{antl.formatMessage('partners.active')}} </option>
        <option value='F'> {{antl.formatMessage('partners.inactive')}} </option>
      </select>
    </div>
    <div class='c-media__content'>
      <button type='submit' class="btn btn-primary">
        {{antl.formatMessage('partners.save')}}
      </button>
    </div>
  </form>

I’ve set autoProcess: false in bodyParser.js

My controller and method looks like this now:

async storePartner({
    auth,
    request,
    response,
    session,
    view
}) {

    const partner = new Partner()

    // const data = request.all()
    // const headers = request.headers()


    // console.log(request)


    partner.name = request.input('name')
    partner.website = request.input('website')
    partner.logo = ""
    partner.description = request.input('description')
    partner.display = request.input('display')
    
    request.multipart.file('logo', {}, async (file) => {
        await Drive.disk('s3').put('partner/' + file.clientName, file.stream)
    
        const imageLink = await Drive.disk('s3').getUrl('partner/' + file.clientName)
    
        partner.logo = imageLink

        // await partner.save()

    })


    await request.multipart.process()
    await partner.save()

    return response.redirect('/')

    // return view.render('partner-image', {
    //     partner: partner.toJSON()
    // })
}

With enctype set to multipart/form-data request.all() returns an empty object.

What am I doing wrong?

If i have a form with just the file upload it works fine, but i want to have it all in the same form to make it easier for the users.

ERROR MESSAGE when trying to save:
Error: insert into campaigns_partners (description, display, logo, name, website) values (DEFAULT, DEFAULT, ‘https://s3.eu-west-1.amazonaws.com/… (correct URL to picture)’, DEFAULT, DEFAULT) - ER_NO_DEFAULT_FOR_FIELD: Field ‘description’ doesn’t have a default value

even though i have filled in description, display, name and website in the form.


#3

@virk @romain.lanz do you guys know or have any solutions on how to fix this?

Request Headers from chrome dev tools:

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate, br
Accept-Language: nb-NO,nb;q=0.9,no;q=0.8,nn;q=0.7,en-US;q=0.6,en;q=0.5
Cache-Control: no-cache
Connection: keep-alive
Content-Length: 212192
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryT0OtwMrjhNcXIsFB
Cookie: lang=4c3961f047266987780bc12c21349842tSgzJWMZOnYLEoA0o6LgnGlQ5QsRprPz7RM0ffbiBIguqdFDzkkpKEa3bOu20VXhE%2Bw6FuhNqaqUZojGsQgv9g%3D%3D; adonis-session=7427f23445c4bae5b2fc9fad38b17500TsilzIJpVNzBMYNdIBunEnSZmjhyptz5FGzYsJI8HL7u7KcpXHXLakDMWHyfBSrASczeXkXCcMCbnkDerKNpDfPz3o2j8Qy4eFJP486dftsvdL%2BNNNW%2BZ6Xe3RrDGhjQ; XSRF-TOKEN=88e90e40b5ec5f52aa53b75846cb3b8b6w4fvruFD8EQPCifL%2BUzN6%2BCOk4181pJo%2F2UIvR7%2B%2BAL1Otr4OQCckCTQJ4AtrxvB6bCS87%2BAJGOUe70KCt%2BygXJxO91gTUUSeFaqj0wQW2KY2lF%2BET2pdlZ1MDLb97D; adonis-session-values=25e5bc9318899813787cd86cfc50d05dNma6HFJhOTjIYOsVOXJ0viiw4il7vKhD%2BQ0bD97AVH1zBFrlKOQbj%2BWYbkBNGBXy2yKQdYtwSuGmRT8upbxhQmnZYKCV9O1xHmIul3iE2tB8nh%2FO4hG30v9eqx12AYzpdSxTku9bfRvBoLbcaEwNZtBd2KIs6z4ZaSPbI0rI%2FOTLKrIfNARkTNSD5xvsZw%2BvfqyOilLpM8FoddzKWVYIQATXNhWwIaUDUwD%2BcZp5enI%3D
DNT: 1
Host: localhost:3333
Origin: http://localhost:3333
Pragma: no-cache
Referer: http://localhost:3333/partnere/ny
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36

if I do NOT include a file in the file input i get this in the request payload in chrome dev tools:

    ------WebKitFormBoundaryA8cftVsLYIqLmXjf
Content-Disposition: form-data; name="_csrf"

xMOzZttx-qvygwbU7-J3nV1xE7XA8U_3xZxQ
------WebKitFormBoundaryA8cftVsLYIqLmXjf
Content-Disposition: form-data; name="name"

heiehei
------WebKitFormBoundaryA8cftVsLYIqLmXjf
Content-Disposition: form-data; name="website"

https://www.google.com
------WebKitFormBoundaryA8cftVsLYIqLmXjf
Content-Disposition: form-data; name="logo"; filename=""
Content-Type: application/octet-stream


------WebKitFormBoundaryA8cftVsLYIqLmXjf
Content-Disposition: form-data; name="description"

dasdf
------WebKitFormBoundaryA8cftVsLYIqLmXjf
Content-Disposition: form-data; name="display"

T
------WebKitFormBoundaryA8cftVsLYIqLmXjf--

#4

If you have disable the auto processing of request you need to do everything yourself so this is normal that request.all() is empty.

Related topic:


#5

Ok. Thanks, but I’m still not sure how to access the regular text input fields from my form. Where do I find this information in the request object? The related topic didnt help much as it has the same problems as I do