0

I'm playing around with Dialogflow, and I would like to return the speech value for the object in the messages array that does not have a platform key assigned to it:

"messages": [
    {
      "type": 0,
      "platform": "skype",
      "speech": "FOO"
    },
    {
      "type": 0,
      "platform": "line",
      "speech": "FOO"
    },
    {
      "type": 0,
      "platform": "facebook",
      "speech": "FOO"
    },
    {
      "type": 0,
      "platform": "telegram",
      "speech": "FOO"
    },
    {
      "type": 0,
      "platform": "kik",
      "speech": "FOO"
    },
    {
      "type": 0,
      "speech": "FOO"
    }
  ]

Currently, I'm returning the value via this ugly process:

messages = messages[messages.length - 1].speech;

My concern is that I do not want to rely on the array returning the platform neutral message as the last element.

Currently, this is what I tried:

 console.log(messages.map(function(obj) {
    if (!(obj.hasOwnProperty('platform'))){
      return obj;
    }
  }));

But I receive an error that states TypeError: messages.map is not a function

How should the map function be designed for such a case

Ry-
  • 218,210
  • 55
  • 464
  • 476
Adib
  • 1,282
  • 1
  • 16
  • 32
  • check what type is messages (what's its constructor), it might not be an array... you can also try iterating it using forEach, for, etc. – Nir Alfasi Jan 28 '18 at 02:39
  • 2
    `messages.messages.filter(m => !m.hasOwnProperty('platform').map(m => m.speech);` – tymeJV Jan 28 '18 at 02:46

3 Answers3

2

Based on the code above I imagine that you have something like this. I think that you are running map on a Map/Associative Array (or JS object) and map doesn't run on that object. Below is a revised sample of what I think will work for you.

let messageMap = {"messages": [
    {
      "type": 0,
      "platform": "skype",
      "speech": "FOO"
    },
    {
      "type": 0,
      "platform": "line",
      "speech": "FOO"
    },
    {
      "type": 0,
      "platform": "facebook",
      "speech": "FOO"
    },
    {
      "type": 0,
      "platform": "telegram",
      "speech": "FOO"
    },
    {
      "type": 0,
      "platform": "kik",
      "speech": "FOO"
    },
    {
      "type": 0,
      "speech": "FOO"
    }
  ]};
  
  // Filter out the messages that don't have a platform defined.
  let platformlessMessages = messageMap['messages'].filter((message) => {
  
    // Return a list of all messages where platform doesn't exists or isn't defined.
    return message.platform === undefined;
  });
  
  console.log(platformlessMessages); // Do whatever you want with that list of objects.
Cogwizzle
  • 550
  • 4
  • 14
2

SOLUTION 1:

You can just loop through messages and look for what you're looking for. Here's a working solution:

var messages =  [
    {
      "type": 0,
      "platform": "skype",
      "speech": "FOO"
    },
    {
      "type": 0,
      "platform": "line",
      "speech": "FOO"
    },
    {
      "type": 0,
      "platform": "facebook",
      "speech": "FOO"
    },
    {
      "type": 0,
      "platform": "telegram",
      "speech": "FOO"
    },
    {
      "type": 0,
      "platform": "kik",
      "speech": "FOO"
    },
    {
      "type": 0,
      "speech": "FOO"
    }
  ]
  for(var obj in messages){
    if(!(messages[obj].hasOwnProperty('platform'))){
        alert(messages[obj].speech);
    }
} 

SOLUTION 2:

You can use the filter and map functions together. Here's a working solution. Hope it helps!

var messages =  [
    {
      "type": 0,
      "platform": "skype",
      "speech": "FOO"
    },
    {
      "type": 0,
      "platform": "line",
      "speech": "FOO"
    },
    {
      "type": 0,
      "platform": "facebook",
      "speech": "FOO"
    },
    {
      "type": 0,
      "platform": "telegram",
      "speech": "FOO"
    },
    {
      "type": 0,
      "platform": "kik",
      "speech": "FOO"
    },
    {
      "type": 0,
      "speech": "FOO"
    }
  ]
  var result = messages.filter(function(obj){
    if (!(obj.hasOwnProperty('platform'))){
      return obj;
    }
}).map(m => m.speech);

alert(result); 
HenryDev
  • 4,685
  • 5
  • 27
  • 64
  • Yup, it's solution 2 what I was looking for. And it's a good solution since it'll return any possible instances where platform does not exist in the object. – Adib Jan 28 '18 at 03:11
1

Assuming that messages is actually defined as an array, I would suggest using the find function instead of map. For example:

console.log(messages.find(function (obj) {
  return !obj.hasOwnProperty('platform');
}));

See also:

How to find first element of array matching a boolean condition in JavaScript?

Andrew
  • 362
  • 3
  • 8
  • But this will return only the first instance, correct? Or will it return multiple instances like map? – Adib Jan 28 '18 at 03:06
  • After reading the docs for find, this answer is good only if I want the first instance, but it doesn't return all possible answers (what map does): https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find – Adib Jan 28 '18 at 03:09