0

I am having a weird issue where if I hardcode a variable, my code works. When the code sets the variable I get weird results. However using console log I can see that the variable IS the correct value. I can literally copy the console value and paste it in place of the variable, and it will work.

function CheckInboxes (boxes, count=0) {
    console.log('-----------------------------------------')
    console.log('checking: ' + boxes[count] + ' | ' + count)
    console.log('-----------------------------------------')

    OpenInbox(boxes[count]).then(box => { //If I set this to 0 or any other value count would be, it works.

        console.log('^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^')
        console.dir(box)
        console.log('^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^')


        if(count < boxes.length -1) {
            var test = count + 1
            CheckInboxes(boxes, test) }
        else
            console.log('FINISHED<<<<<<<<<<<<<<<<<<<<<<<<<<')


    })


}

boxes is an array of mailbox names ie "inbox", "draft", "etc"

The OpenInbox function returns an object defining that inbox (folder). This includes the name. The name should match the first parameter. So OpenInbox('inbox') returns an object with a name property of "inbox" because the library searches for a folder with that name and returns the object associated with it.

The problem is, this is not what happens if its not hardcoded. Its completely random. The returned object could be draft or any other folder. Sometimes it happens to be the right folder.

> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> ----------------------------------------- checking: Inbox | 0
> ----------------------------------------- opening...Inbox

This clearly shows its 0 and its passing "Inbox". The result will be random though. HOWEVER, if I replace

OpenInbox(boxes[count])

with

OpenInbox(boxes[0]) //or just 'inbox' 

It works. Of course this isn't practical...

So I am very confused. Console clearly shows whats being passed, yet it doesn't work unless I hardcode the value outputted in console. This shouldn't be possible. Am I missing something?

UPDATE:

So by accident I add this code:

console.dir(box)
        console.log(box.name)
        console.log(JSON.stringify(box))

The result is...

enter image description here

Notice the underlined parts are completely different.

This leads me to think its a bug in chrome console.log or something because stringify shows the data I'm expecting.

1
  • I notice that OpenInbox returns a promise - that suggests it's doing something asynchronous, and you're probably seeing the result you do because you're not handling the callback or promise correctly. Post your OpenInbox code & we can see for sure. Commented Jul 11, 2017 at 4:36

2 Answers 2

2

To make promises work properly with recursion and keep the chain in order, you need to return the inner promises so everything is properly chained together. Note the places where I added return:

function CheckInboxes (boxes, count=0) {
    console.log('-----------------------------------------')
    console.log('checking: ' + boxes[count] + ' | ' + count)
    console.log('-----------------------------------------')

    // return this promise
    return OpenInbox(boxes[count]).then(box => {

        console.log('^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^')
        console.dir(box)
        console.log('^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^')

        if(count < boxes.length -1) {
            // return this promise
            return CheckInboxes(boxes, count + 1);
        } else {
            console.log('FINISHED<<<<<<<<<<<<<<<<<<<<<<<<<<');
            // Is there a proper value to return here?
        }
    });
}

The way you had it, you were creating new independent promise chains which would interleave with each other rather than run serially.


P.S. There are some known issues with console.log(obj) in Chrome. If you immediately change obj right after you do console.log(obj), then Chrome might not output what you wanted. It appears that the obj is not immediately copied and the console.log() is not immediately carried out (perhaps because of process boundaries) so if you immediately modify obj, it might get changed before console.log() actually does its work. The usually work-around when you see this happening is exactly what you did (use JSON.stringify()). Fortunately, this doesn't happen that frequently, but when it does it can be very confusing. I'm just very careful in my code to notice if I'm immediately modifying an object that I just output with console.log() and, if so, I either output just the desired property or I use JSON.stringify().

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks so much for the detailed answer and code! I wasn't aware of the known issue. Was super frustrating to say the least. I probably spent over and hour looking for the "bug"
1

the boxes could be an object not array. check your boxes with Object.keys(boxes)

if it's string or number ..

{
  "0": {..},
  "1": {..},
}
// OR
{
  0: {..},
  1: {..},
  ...
}

1 Comment

if you're interested I updated my question with a new finding

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.