Reputation: 1664
I have an object with some properties such as;
integrationConfig = {
iconEmoji: ':myIconEmoji:',
team: 'myTeam',
text: 'myText',
channel: 'myChannel',
botName: 'myBot'
}
I am passing this object to a function below as shown (attachments
is not important).
return await this.pushToSlack(...integrationConfig, attachments);
Importantly, this function is part of an NPM Package, so I don’t want to change the function declaration.
The function is declared like this:
exports.pushToSlack = function (channel, text, botName, iconEmoji, team, attachments, cb = function () {}) {
// […]
}
I put some breakpoint to the pushToSlack
function but the debugger didn’t jump into that line. I guess the function is not called somehow. I also receive this error:
Debug: internal, implementation, error
TypeError: object is not iterable (cannot read property Symbol(Symbol.iterator))
at Function.all (<anonymous>)
Have you got any idea?
Upvotes: 2
Views: 2035
Reputation: 2669
so you have function
const pushToSlack = function (channel, text, botName, iconEmoji, team, attachments, cb = function () {}) {
this function accepts 7 arguments.
You have good idea to spread an object integrationConfig
, hoping that it will become 7 arguments.
However spreading an object will just clone the exact same object with exact same property.
const obj = {...integrationConfig}
is equal to ONE
Object.
You can instead pass an array and spread it.
pushToSlack(...Object.values(integrationConfig))
But an object does not guarantee the order of the key. so it could be
// order is not guaranteed!!!
...Object.values(integrationConfig) === [botName, channel, iconEmoji, team, text]
// or
...Object.values(integrationConfig) === [channel, botName, iconEmoji, team, text]
// or
...Object.values(integrationConfig) === [team, botName, iconEmoji, channel, text]
However your function need a fix order of arguments.
I believe you can do like this
const integrationConfig = {
iconEmoji: ':myIconEmoji:',
team: 'myTeam',
text: 'myText',
channel: 'myChannel',
botName: 'myBot'
}
const {iconEmoji, team, text, channel, botName} = integrationConfig
pushToSlack(channel, text, botName, iconEmoji, team, etc);
Upvotes: 2
Reputation: 22320
Spread syntax is not usable for that
use Destructuring assignment
integrationConfig =
{ iconEmoji : ':myIconEmoji:'
, team : 'myTeam'
, text : 'myText'
, channel : 'myChannel'
, botName : 'myBot'
}
the call :
return await this.pushToSlack( integrationConfig, attachments);
the function :
exports.pushToSlack = function ({channel, text, botName, iconEmoji, team}, attachments, ...
//..Destructuring assignment....^.......................................^
// Arguments can be in any order you want
// and no obligation to have all of them
Upvotes: 1
Reputation: 19485
If you cannot change the parameter list of the function, you’ll have to define the order the arguments are expected in, then map your object onto this order:
const argumentOrder = [
"channel",
"text",
"botName",
"iconEmoji",
"team"
];
// […]
return await this.pushToSlack(...argumentOrder.map((property) => integrationConfig[property]), attachments);
The error you’re getting means that func(...integrationConfig)
won’t work. Yes, the function is never called. There’s a distinction between object spread and iterable spread. Arguments and arrays use iterable spread, which means that two conditions must be met: firstly, the value you want to spread must be non-nullish; and secondly, the value must be iterable, i.e. something that has Symbol.iterator
. Object spread only checks the first condition.
You could, theoretically, add such a symbol property into your object, which would allow you to use your original syntax:
const integrationConfig = {
iconEmoji: ":myIconEmoji:",
team: "myTeam",
text: "myText",
channel: "myChannel",
botName: "myBot",
*[Symbol.iterator](){
yield this.channel;
yield this.text;
yield this.botName;
yield this.iconEmoji;
yield this.team;
}
};
// […]
return await this.pushToSlack(...integrationConfig, attachments);
Upvotes: 3