1

I have an object with a Value field. This field contains a very long string (base64). When using console.log, the field seems to contain the string, however, when just printing out this one field, I just get an empty string:
enter image description here

I'm trying to send this object through a REST service, but it just sends the empty string instead of the correct value.

What is going on here? I've used these kind of strings before and it worked fine, but now it looks like I'm missing something important.

To make it clear, this gets the above output:

console.log(myObject);

This prints an empty string:

console.log(myObject.Value);

EDIT: This is how the Value is assigned:

    for (var i = 0; i < vm.data.profileSettings.length; i++) {
        (function (i) {
            var setting = vm.data.settings.filter(function(setting) { return setting.Id == vm.data.profileSettings[i].Id });

            if (setting[0].Type == 2 && vm.data.profileSettings[i].copiedValue && typeof(vm.data.profileSettings[i].copiedValue) == 'object') {
                Upload.base64DataUrl(vm.data.profileSettings[i].copiedValue)
                    .then(function(response) {
                        var splitted =  response.split(",");

                        vm.data.profileSettings[i].Value = splitted[1];
                    });

            }
        })(i);
    }

    profileDataService.saveProfileSettings(vm.data.selectedProfile.Id, vm.data.profileSettings)
    .then(function(response) {
        vm.success = true;
    });
Bv202
  • 3,624
  • 11
  • 41
  • 76
  • console is not a snapshot when you log objects unless you stringify them. Sounds like value is added after you log the whole object. Show us the code – charlietfl Sep 26 '16 at 12:42
  • That what I was supecting already. However, I thought the way I wrote the code would make sure the API call (saveprofileSettings) would not be executed before the loop ends. I've added the code, thanks – Bv202 Sep 26 '16 at 12:47
  • 1
    But `Upload` is asynchronous – charlietfl Sep 26 '16 at 12:48
  • Yes, but wouldn't putting the whole loop in a new function block solve that issue? If not, what can I do to assure the call is only made when the async Upload calls are completed? – Bv202 Sep 26 '16 at 12:49

2 Answers2

1

Upload() is asynchronous so you need all the Upload to complete before you send your final data since that data is dependent on responses from uploads.

You can create array of upload promises and use $q.all() to run code when all of those promises have resolved


Create empty array before the loop and push each upload promise into that array

var uploadPromises = []

Then change

Upload.base64DataUrl(vm.data.profileSettings[i].copiedValue)
                .then(function(response) {
                   // do stuff with response
                });

To

var req =  Upload.base64DataUrl(vm.data.profileSettings[i].copiedValue)
                .then(function(response) {
                   // do stuff with response
                });
 uploadPromises.push(req);

Now wrap your final request

$q.all(uploadPromises ).then(function(){    
    profileDataService.saveProfileSettings(...)
}).catch(function(err){
   // do something when any upload promise is rejected
});

Note you will need to determine strategy if any upload promise gets rejected. You can use a catch on upload promises themselves to also resolve that promise if that's what you want to do so final request will always be made

charlietfl
  • 164,229
  • 13
  • 110
  • 143
  • Thanks a lot, your solution seems to work perfectly! Also thanks for the clear explanation =) – Bv202 Sep 26 '16 at 13:06
0

Im guessing that your long String is a file encoded to base64. Then you can use btoa() and atob() to convert to and from base64 encoding.

You can have a look at this answer: https://stackoverflow.com/a/247261/2886514

Community
  • 1
  • 1
Anouar
  • 20
  • 1
  • 12