4

my Meanjs app is supposed to upload a logo into a nested schema, within my UserSchema. I am able to successfully upload the file, as I am able to store a profile photo for the user successfully. But when I am trying to save an image into the nested Schema, it fails.

My model looks something like this:

ClubSchema = {name:String,
              logo:Buffer};

UserSchema = {name:String,
              photo:Buffer,
              club:[ClubSchema]
             }

I am able to successfully insert all the data into my ClubSchema, but not the logo.

My client.controller.js

    var user = new Users($scope.user);
    console.dir(user.club);      //I can see the logo here
    for(var i = 0;i<user.club.length;i++){
        user.club[i].logo = $scope.uploadedLogos[i];  //Still trying to force it into the object

        user.club[i].hasLogo = true;    //Mysterious hasLogo = false appears
    }
    user.$update(function(response) {
        $scope.success = true;
        console.log('Inside scope success User is ');
        console.dir(user);               //hasLogo=false appears in this and no logo
        $location.path('/');
        }, function(response) {
             $scope.error = response.data.message;
        });

My server.controller.js

if (user) {
    // Merge existing user
    user = _.extend(user, req.body);
    user.updated = Date.now();
    user.displayName = user.name;

    user.save(function(err) {
        if (err) {
            return res.status(400).send({
                message: errorHandler.getErrorMessage(err)
            });
        } else {
            req.login(user, function(err) {
                if (err) {
                    res.status(400).send(err);
                } else {
                    res.json(user);
                }
            });
        }
    });
} else {
    res.status(400).send({
        message: 'User is not signed in'
    });
}

The hasLogo field is completely baffling because no such assignment exists in my code. I added the hasLogo = true, hoping that somehow it would set the hasLogo to true and upload the image then, but that doesn't work either. I have no idea where this hasLogo is coming from. After the hasLogo = true loop, if I print the object, I can see two hasLogo fields, one true and the other false. After the $update success, it is always false. My model does not contain a hasLogo field.

kvnam
  • 1,285
  • 2
  • 19
  • 34
  • user.club[i].logo is where logo is present right..? what does $scope.uploadedLogos[i] have.? – SUNDARRAJAN K Apr 16 '15 at 08:09
  • $scope.uploadedLogos[i] is just a separate array I created to take a secondary storage of the logos being uploaded and then reassigning them to $scope.user.club[i].logo in case it got removed. Does not help coz it still get removed in my final user object which I am trying to update. – kvnam Apr 16 '15 at 14:02
  • Has no real relevance to the final user object. Was just something I was trying. The final var user that I am trying to update using $scope.user still does not contain the logos – kvnam Apr 16 '15 at 14:53
  • is the logo you getting from the client is in this format? "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAc4AAAHOCAMAAAAmOBmCAAAAM1BMVEUyicg9j8pJlcxUm85godBrp9J3rdSCs9aNudiZv9ukxd2wy9+70eHH1+PS3eXe4+fp6elALxDWAAAMG0lEQVR42u3da7qkKgyF4aiUhYrA/Ed7fvT96e7Te3sjJN+aQfkWEKKiVGIowiWAk8BJ4CRwwkngJHASOAmccBI4CZwETgInnAROAieBk8AJJ4GTwEngJHDCSeAkcBI4CZxwEjgJnAROAiecBE4CJ4ETTgIngZPASeCEk8BJ4CRwEjjhJHASOAmcBE44CZwETgIngRNOAieBk8BJvHCmtMY4h18zx7ikVODsyHGNYZL/zxTiYlHVFGdJ8TXKxzOGuBU4NSav8yRHMs5rhlNVtvcoZzLORkapGBiWL7kiYclwtl4tl0muy9S9aNecF==" – SUNDARRAJAN K Apr 17 '15 at 04:57
  • Yup, I am using ng-file-upload directive to upload files. The user's photo uploads perfectly using this directive. Btw I found a workaround solution to this by making Club a separate module altogether and creating/ updating it separately from the User model. Not sure if this is the right way to go, but it works. Would love to know what is wrong with the original implementation though. – kvnam Apr 17 '15 at 10:28

1 Answers1

0

This is the way i used MEAN.JS for file upload.

Model

  var UserSchema = new mongoose.Schema({
  name:{type:String,required:true},
  photo:Buffer  // Image
  });

Server Controller

var userPicture = function(req,res){             // Stores Picture for a user matching the ID.
    user.findById(req.param('id'), function (err, user) {
        console.log(req.files) // File from Client
        if(req.files.file){   // If the Image exists
            var fs = require('node-fs');
            fs.readFile(req.files.file.path, function (dataErr, data) {
                if(data) {
                    user.photo ='';
                    user.photo = data;  // Assigns the image to the path.
                    user.save(function (saveerr, saveuser) {
                        if (saveerr) {
                            throw saveerr;
                        }
                        res.json(HttpStatus.OK, saveuser);                        
                    });
                }
            });
            return
        }
        res.json(HttpStatus.BAD_REQUEST,{error:"Error in file upload"});
    });
};

Client Controller

    $scope.saveuserImage =  function(){
        $scope.upload = $upload.upload({  // Using $upload
            url: '/user/'+$stateParams.id+'/userImage',  // Direct Server Call.
            method:'put',
            data:'',  // Where the image is going to be set.
            file: $scope.file
        }).progress(function (evt) {})
            .success(function () {
                var logo = new FileReader();  // FileReader.

                $scope.onAttachmentSelect = function(file){
                    logo.onload = function (e) {
                        $scope.image = e.target.result;  // Assigns the image on the $scope variable.
                        $scope.logoName = file[0].name; // Assigns the file name.
                        $scope.$apply();
                    };
                    logo.readAsDataURL(file[0]);
                    $scope.file = file[0];
                    $scope.getFileData = file[0].name
                };
                location.reload();
                $scope.file = "";
                $scope.hideUpload = 'true'
            });
        $scope.getFileData = '';
     //        location.reload()
    };

Html

<input ng-file-select="onAttachmentSelect($files)" ng-model="getFileData" name="upload" type="file" required="true">

The ng-file-select is used to get the file from the client.

This works fine for me. Hope this helps.

SUNDARRAJAN K
  • 2,237
  • 2
  • 22
  • 38
  • I am able to upload the image successfully already. The problem was in inserting it into a nested field within my mongodb document. – kvnam Apr 23 '15 at 13:47