1

my problem is that whenever a new client is created, all the values are null in the database except the id, the name, responsable and the logo. i dont think i did a programmation mistake, so i think it is a case of callbacks race but i cant found the solution. P.S : the problem occure only if i select and send an image file to be uploaded, in the other case, the client values are stored correctly. P.S 2 : the problem occure in my remote server only, in local environnement all is ok !

Than you very much !

UPDATE : i included the code for my create.ejs view

This is the code of the store method in my ClientService :

store: function(req, done) {
  var name = req.param('name'),
    town = req.param('town'),
    adress = req.param('adress'),
    postalCode = req.param('postalCode'),
    telephone = req.param('telephone'),
    email = req.param('email'),
    fax = req.param('fax'),
    responsable = req.param('responsable'),
    website = req.param('website'),
    activity = req.param('activity');
  comments = req.param('comments');

  Client.create({
    name: name,
    town: town,
    adress: adress,
    postalCode: postalCode,
    telephone: telephone,
    fax: fax,
    responsable: responsable,
    website: website,
    activity: activity,
    email: email,
    comments: comments
  }).exec(function(err, client) {
    if (err) console.log(err);
    req.file('logo').upload(
      {
        dirname: sails.config.appPath + sails.config.params.logos
      },
      function(err, logo) {
        if (err) return done(err, null);
        if (logo.length !== 0) {
          client.logo = require('path').basename(logo[0].fd);
        } else {
          client.logo = 'default.png';
        }
        client.save(function(err) {
          return done(null, client);
        });
      }
    );
  });
}

And this is the code for the EJS view :

<div class="portlet-body form">
                        <!-- BEGIN FORM-->
                        <form action="store" method="POST" class="form-horizontal" enctype="multipart/form-data">
                            <div class="form-body">
                                <div class="row">
                                    <div class="col-md-6">
                                        <div class="form-group form-md-line-input has-success form-md-floating-label form-create">
                                            <div class="input-icon">
                                                <input type="text" class="form-control" name="name">
                                                <label for="form_control_1">Nom du Client</label>
                                                <i class="fa fa-institution"></i>
                                            </div>
                                        </div>
                                    </div>
                                    <div class="col-md-6">
                                        <div class="form-group form-md-line-input has-success form-md-floating-label form-create">
                                            <div class="input-icon">
                                                <input type="text" class="form-control" name="activity">
                                                <label for="form_control_1">Activité</label>
                                                <i class="icon-star"></i>
                                            </div>
                                        </div>
                                    </div>
                                    </div>
                                <div class="row">
                                    <div class="col-md-6">
                                         <div class="form-group form-md-line-input has-success form-md-floating-label form-create">
                                            <div class="input-icon">
                                                <input type="text" class="form-control" name="responsable">
                                                <label for="form_control_1">Responsable</label>
                                                <i class="icon-user"></i>
                                            </div>
                                        </div>
                                    </div>
                                    <div class="col-md-6">
                                     <div class="form-group" style="margin-left:15px;">
                                        <div class="form-photo-label-form" >
                                                &nbsp;&nbsp;<i class="icon-picture icon-create"></i>&nbsp;&nbsp; 
                                                <label for="form_control_1" class="form-photo-create" >Photo </label>
                                        </div>
                                        <br>
                                        <div class="fileinput fileinput-new" data-provides="fileinput">
                                                    <span class="btn green btn-file">
                                                    <span class="fileinput-new"> Selectionner Fichier </span>
                                                    <span class="fileinput-exists"> Changer </span>
                                                    <input type="file" name="logo"> </span>
                                                    <span class="fileinput-filename"> </span> &nbsp;
                                                     <a href="javascript:;" class="close fileinput-exists" data-dismiss="fileinput"> </a>
                                        </div>
                                    </div>
                                    </div>
                                </div>
                                <div class="row">
                                    <div class="col-md-6">
                                         <div class="form-group form-md-line-input has-success form-md-floating-label form-create">
                                            <div class="input-icon">
                                                <input type="text" class="form-control" name="email">
                                                <label for="form_control_1">Email</label>
                                                <i class="fa fa-inbox"></i>
                                            </div>
                                        </div>
                                    </div>
                                    <div class="col-md-6">
                                         <div class="form-group form-md-line-input has-success form-md-floating-label form-create">
                                            <div class="input-icon">
                                                <input type="text" class="form-control" name="adress">
                                                <label for="form_control_1">Adresse</label>
                                                <i class="icon-home"></i>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                                <div class="row">
                                     <div class="col-md-6">
                                        <div class="form-group form-md-line-input has-success form-md-floating-label form-create">
                                            <div class="input-icon">
                                                <input type="text" class="form-control" name="postalCode">
                                                <label for="form_control_1">Code postale</label>
                                                <i class="fa fa-send"></i>
                                            </div>
                                        </div>
                                    </div>
                                    <div class="col-md-6">
                                        <div class="form-group form-md-line-input has-success form-md-floating-label form-create">
                                            <div class="input-icon">
                                                <input type="text" class="form-control" name="town">
                                                <label for="form_control_1">Ville</label>
                                                <i class=" fa fa-map"></i>
                                            </div>
                                        </div>
                                    </div>
                                    <!--/span-->
                                </div>
                                <div class="row">
                                     <div class="col-md-6">
                                        <div class="row">
                                            <div class="col-md-12">
                                                <div class="form-group form-md-line-input has-success form-md-floating-label form-create">
                                                <div class="input-icon">
                                                <textarea class="form-control" rows="3" style="height: 192px; resize:none " name="comments"></textarea>
                                                <label for="form_control_1">Commentaire</label>
                                                <i class=" fa fa-edit"></i>
                                                </div>
                                            </div>
                                            </div>
                                        </div>
                                     </div>
                                     <div class="col-md-6">
                                        <div class="row">
                                            <div class="col-md-12">
                                                <div class="form-group form-md-line-input has-success form-md-floating-label form-create">
                                                    <div class="input-icon">
                                                        <input type="text" class="form-control" name="telephone">
                                                        <label for="form_control_1">Telephone</label>
                                                        <i class="icon-screen-smartphone"></i>
                                                    </div>
                                                </div>
                                            </div>
                                        </div>
                                        <div class="row">
                                            <div class="col-md-12">
                                                <div class="form-group form-md-line-input has-success form-md-floating-label form-create">
                                                    <div class="input-icon">
                                                        <input type="text" class="form-control" name="fax">
                                                        <label for="form_control_1">Fax</label>
                                                    <i class="fa fa-fax"></i>
                                                    </div>
                                                </div>
                                            </div>
                                        </div>
                                        <div class="row">
                                            <div class="col-md-12">
                                                <div class="form-group form-md-line-input has-success form-md-floating-label form-create">
                                                    <div class="input-icon">
                                                        <input type="text" class="form-control" name="website">
                                                        <label for="form_control_1">Site Internet</label>
                                                        <i class=" fa fa-internet-explorer"></i>
                                                     </div>
                                                </div>
                                            </div>
                                        </div>
                                    </div>

                                </div>
                            </div>

                    <div class="form-actions right">
                        <button type="button" class="btn default">Annuler</button>
                        <button type="submit" class="btn green"><i class="fa fa-check"></i> Enregistrer</button>
                    </div>
                </form>
Aissam Jadli
  • 75
  • 11
  • You should return in your `if (err) console.log(err);` – Phix Dec 06 '17 at 00:23
  • check my answer – num8er Dec 06 '17 at 00:47
  • Do you use `FormData` on the client side to submit this request? When you use FormData to upload a file, you have to attach the file last - data attached after the file will be lost. – arbuthnott Dec 06 '17 at 12:20
  • @arbuthnott I told him in comments to my answer to add view part to see what's in frontend. Seems like he keeps that in secret :D – num8er Dec 06 '17 at 13:16
  • sorry for being late ! I updated the question – Aissam Jadli Dec 06 '17 at 13:29
  • 1
    @AissamJadli now from this part as far I understand that You've to exactly use `req.body` object instead of `req.param`. Reason is when You push the file it goes as `formData` and being handled by some middleware for file upload operation. Try to do `console.log(req.body)` inside Your `store` action and see if Your fields are there. – num8er Dec 06 '17 at 13:35
  • 2
    I think when you upload with `enctype="multipart/form-data"`, the form fields become part of the file stream, and it should require some work to access them. Don't know how in node. Found some related questions: https://stackoverflow.com/questions/15105322/sending-additional-data-with-multipart – arbuthnott Dec 06 '17 at 14:04
  • 1
    @arbuthnott You're right, that's what I'm trying to explain him. That's what I'm talking to use `req.body` for `POST` methods. – num8er Dec 06 '17 at 14:11
  • @num8er I know that in sails, req.param() is a shortcut that retrieves from several places including req.body... From what I've read, I *suspect* that it will be harder than just `req.body`? Worth a try of course! – arbuthnott Dec 06 '17 at 14:15
  • @arbuthnott in fact this form is dedicated to do POST request - so it's nobrainer to understand that `req.body` will have post fields and file will pass through multer and be available as `req.file`. – num8er Dec 06 '17 at 14:18

2 Answers2

2

Nothing mysterious (: Your problem is that You use req.param instead of req.body

And Your code is simply should look like this:

const path = require('path'); // somewhere in same module at the top

store: (req, done) => {

  Client
    .create(req.body)
    .exec((err, client) => {
      if(err) {
        // no need to go further 
        // if You cannot create database record
        return done(err);
      } 

      const dirname = path.join(sails.config.appPath, sails.config.params.logos); // safely concatenates paths based on OS

      req
        .file('logo')
        .upload({dirname}, (err, logo) => {
          if (err) {
            // we created record (client) 
            // but could not save the file
            // it should not be a stopper
            console.error(err);
          }

          client.logo = (logo) ? path.basename(logo[0].fd) : 'default.png';

          client.save((err) => {
            if(err) {
              // just log the error and continue
              console.error(err);
            }
            done(null, client);
          });
        });
    });
}



P.S. When You pass req.body (or any other) object to Client.create don't worry about object contents, just define field constrains in You model file, ODM (or ORM) will just handle validation automatically based on constraints and will prevent from creating null valued fields

Example:

module.exports = {

  attributes: {

    name: {
      // it requires field name:
      //  to be defined (required: true), 
      //  to be string (type), 
      //  to have at least 2 symbols,
      //  to not exceed 100 symbols
      type: 'string',
      required: true,
      minLength: 2,
      maxLength: 100
    },

    email: {
      // it requires field email:
      //  to be defined (required: true), 
      //  to be email (type), 
      //  to be unique among documents, records, rows
      type: 'email',
      required: true,
      unique: true
    },
    ... and so on ...
  }
}

More about validation here

num8er
  • 18,604
  • 3
  • 43
  • 57
  • Thank you for your response. But this not explain why the values are retrived correctly if i dont upload the logo ! – Aissam Jadli Dec 06 '17 at 07:55
  • @AissamJadli well to explain it we have to debug that situation. Open inspect on browser, go to network tab, check preserve log checkbox and do form posting and see what fields really being passed to Your app. From Your talk I can only guess that You've html issues, because without file it works ok, so there's problem on different level, so please provide the view file of that form in Your question, route definition for that action (if it's custom route). – num8er Dec 06 '17 at 09:11
  • Thank you for your response! i don't think that the problem reside in fields because the values are passed if i dont use the file input. – Aissam Jadli Dec 06 '17 at 13:32
1

Thanks everybody. I solved the problem by putting the file input at the end the form. Like you suggested, the values after the file input were reset after the upload of the file

Aissam Jadli
  • 75
  • 11
  • congrats, interesting situation, but I would like to see what if not to move file field to the end and fix issue. – num8er Dec 07 '17 at 02:17