Why Does it Seem Like Javascript Doesn't Know This is an Array?


#1

I’m getting a console error: “options.requestPermissions.join is not a function”. Chrome dev tools shows the error on this line of facebook_client.js:

  var scope = "email";
  if (options && options.requestPermissions)
    scope = options.requestPermissions.join(','); //<==ERROR

This is a javascript array join() call. I would think that as long as options.requestPermissions is an array, it should work. But, it is an array. Here’s a screenshot from Chrome dev tools:

What am I missing?


#2

Maybe you’re seeing the value of options.requestPermissions in your debugger after it was used in Facebook.requestCredential, and by that time is was properly set?


#3

I tried to reproduce this in jsfiddle and it seems to work with the code you are showing.

Pardon this newb question, but what is Local. Why is the field ‘a’ undefined?


#4

Here’s the code that calls facebook_client.js:

    performSocialLogin(service){ <== service == 'loginWithFacebook'
        const options = {
            requestPermissions: ['user_friends', 'public_profile', 'email']
        };
        if ( service === 'loginWithTwitter' ) {
            delete options.requestPermissions;
        }

        Meteor[service]({
            requestPermissions: options
        }, (err) => {
            if (err) {
                console.log('Login error - ', err);
            } else {
                console.log('Login error - ', err);
            }
        });
    }

Right before the call to Meteor.loginWithFacebook, options.requestPermissions is an array:

I step into that call, and options.requestPermissions is transformed into an object!

Why is that happening?


#5

Edit-- this was supposed to be addressed to @ddddave.

Local is the scope of the currently executing code block. The variables that exist within that scope are listed. You will see enclosing code blocks marked with the label, “Closure”, and the global space marked with the label, “Global.”

a is undefined because the code that defines it hasn’t yet been called. :slight_smile:


#6

It looks like a small typo - when you first see the proper array in your debugger, you’re seeing the const options you’re setting on the second line of your code snippet. When you make the following call however:

...
Meteor[service]({
  requestPermissions: options
},
...

You’re passing in a new object with a requestPermissions property, that has a value of your options const, which also has a requestPermissions key. So you’re really passing in:

...
Meteor[service]({
  requestPermissions: {
    requestPermissions: ['user_friends', 'public_profile', 'email']
  }
},
...

#7

@hwillson That was it. Thank you very much!

The revised code is:

      Meteor[service](
            options
        , (err) => {
            if (err) {
                console.log('Login error - ', err);
            } else {
                console.log('Login error - ', err);
            }
        });