# Creating percentages from responses

**URL:** <https://discourse.nodered.org/t/creating-percentages-from-responses/12097>\
**Category:** General\
**Created:** [12 June 2019 07:52 UTC](https://discourse.nodered.org/t/creating-percentages-from-responses/12097 "2019-06-12T07:52:56Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![graphicsop](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/graphicsop/32/8663_2.png) [@graphicsop](https://discourse.nodered.org/u/graphicsop)\
**Post date:** [12 June 2019 07:52 UTC](https://discourse.nodered.org/t/creating-percentages-from-responses/12097/1 "2019-06-12T07:52:56Z")

</div>

Hi all...

Apologies, I'm a very new user with no experience in coding...

Does anyone have any ideas on how best to count from 4 responses in a message and create percentage results to be sent via OSC?

Would it be possible to make this with nodes alone or does it require Javascript?

The message format the host app outputs is below:  
{  
"id" : 484993,  
"content\_type" : null,  
"object\_id" : null,  
"response\_obj" : {  
"id" : 227825,  
"pollresponse" : 484993,  
"response" : [42834, 42835, 42836, 42837]  
},  
"response\_type" : "choice",  
"is\_active" : true,  
"created" : "2019-06-11T14:40:57.794723Z",  
"updated" : "2019-06-11T14:45:10.646746Z",  
"anonymous\_id" : null,  
"archive" : null,  
"poll" : 31754,  
"person" : 355244  
}

Any input would be greatly appreciated.  
Many thanks  
Patrick

---

<div class="post-metadata">

**Author:** ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)\
**Post date:** [12 June 2019 08:07 UTC](https://discourse.nodered.org/t/creating-percentages-from-responses/12097/2 "2019-06-12T08:07:54Z")

</div>

You have not made it clear (to me at least) exactly what percentages you want to see. Perhaps tell us exactly what you want to get from the data you have showed, and how it is calculated.

---

<div class="post-metadata">

**Author:** ![knolleary](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/knolleary/32/3_2.png) [@knolleary](https://discourse.nodered.org/u/knolleary)\
**Post date:** [12 June 2019 08:16 UTC](https://discourse.nodered.org/t/creating-percentages-from-responses/12097/3 "2019-06-12T08:16:31Z")

</div>

Hi Patrick,

I assume you mean you want the `payload.response_obj.response` array of values to be turned into their equivalent percentages. Is `payload.response_obj.pollresponse` the total? Or do you also need to sum the values in that array first to get the total?

---

<div class="post-metadata">

**Author:** ![graphicsop](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/graphicsop/32/8663_2.png) [@graphicsop](https://discourse.nodered.org/u/graphicsop)\
**Post date:** [12 June 2019 08:19 UTC](https://discourse.nodered.org/t/creating-percentages-from-responses/12097/4 "2019-06-12T08:19:53Z")

</div>

Sorry for not making myself clear...

The host application is a voting app with 4 options of response -  
"response" : [42834, 42835, 42836, 42837]

Option a - 42834  
Option b - 42835  
Option c - 42836  
Option d - 42837

I need to be able to collect all the responses and output the percentage results - 0-100 between all the responses that come through.

Does that make sense?

---

<div class="post-metadata">

**Author:** ![knolleary](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/knolleary/32/3_2.png) [@knolleary](https://discourse.nodered.org/u/knolleary)\
**Post date:** [12 June 2019 08:28 UTC](https://discourse.nodered.org/t/creating-percentages-from-responses/12097/5 "2019-06-12T08:28:51Z")

</div>

There isn't a node I know of that will just do that (although the flow library is large and something may lurk in there).

Given the core palette of nodes, you're left with either the Function node or Change node.

With the Change node, you can configure it to set `msg.results` to the Expression:

```auto
$map(payload.response_obj.response, function($v) { $round(100*$v/( $sum := function($i, $j){$i + $j}; $reduce(payload.response_obj.response, $sum) ),2)})

```

This uses the JSONata expression language.

Or, a Function node with the code:

```auto
var total = 0;
msg.results = [];
// First get the total from the array
msg.payload.response_obj.response.forEach(function(v) {
   total += v
});
// The calculate each value's percentage to 2 decimal places
msg.payload.response_obj.response.forEach(function(v) {
   msg.results.push( (100*v/total).toFixed(2) )
});
return msg;

```

Both will give you `msg.results` with the array of percentages.

---

<div class="post-metadata">

**Author:** ![graphicsop](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/graphicsop/32/8663_2.png) [@graphicsop](https://discourse.nodered.org/u/graphicsop)\
**Post date:** [12 June 2019 08:38 UTC](https://discourse.nodered.org/t/creating-percentages-from-responses/12097/7 "2019-06-12T08:38:21Z")

</div>

Thank you very much...

Would this script give me the ability to output the 4 separate percentages and link them into an OSC output node?

---

<div class="post-metadata">

**Author:** ![graphicsop](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/graphicsop/32/8663_2.png) [@graphicsop](https://discourse.nodered.org/u/graphicsop)\
**Post date:** [12 June 2019 10:30 UTC](https://discourse.nodered.org/t/creating-percentages-from-responses/12097/8 "2019-06-12T10:30:11Z")

</div>

How do I get the 4 options into that script and output 4 separate percentages?

---

<div class="post-metadata">

**Author:** ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)\
**Post date:** [12 June 2019 10:45 UTC](https://discourse.nodered.org/t/creating-percentages-from-responses/12097/9 "2019-06-12T10:45:59Z")

</div>

Does the flow given not work?

---

<div class="post-metadata">

**Author:** ![graphicsop](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/graphicsop/32/8663_2.png) [@graphicsop](https://discourse.nodered.org/u/graphicsop)\
**Post date:** [12 June 2019 10:54 UTC](https://discourse.nodered.org/t/creating-percentages-from-responses/12097/10 "2019-06-12T10:54:42Z")

</div>

When I connect the input MQTT node into the funtion node I get the following error in the Debug window..."TypeError: Cannot read property 'response' of undefined"

---

<div class="post-metadata">

**Author:** ![graphicsop](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/graphicsop/32/8663_2.png) [@graphicsop](https://discourse.nodered.org/u/graphicsop)\
**Post date:** [12 June 2019 11:14 UTC](https://discourse.nodered.org/t/creating-percentages-from-responses/12097/11 "2019-06-12T11:14:01Z")

</div>

As I said, I'm very new to this so I probably missing something very simple...

---

<div class="post-metadata">

**Author:** ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)\
**Post date:** [12 June 2019 12:40 UTC](https://discourse.nodered.org/t/creating-percentages-from-responses/12097/12 "2019-06-12T12:40:28Z")

</div>

> [@graphicsop](#):
>
> TypeError: Cannot read property 'response' of undefined"

That is presumably coming from one of the lines like  
`msg.payload.response_obj.response.forEach(..`  
and means that msg.payload does not contain and object called response\_obj even though the data you showed at the start does contain such an object.  
Put a debug node showing what is going into the function node and copy/paste what you see here.

---

<div class="post-metadata">

**Author:** ![graphicsop](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/graphicsop/32/8663_2.png) [@graphicsop](https://discourse.nodered.org/u/graphicsop)\
**Post date:** [12 June 2019 12:45 UTC](https://discourse.nodered.org/t/creating-percentages-from-responses/12097/13 "2019-06-12T12:45:42Z")

</div>

I selected the second option and the following is what can through to the debug node:

"{"id": 484993, "content\_type": null, "object\_id": null, "response\_obj": {"id": 227825, "pollresponse": 484993, "response": [42834]}, "response\_type": "choice", "is\_active": true, "created": "2019-06-11T14:40:57.794723Z", "updated": "2019-06-12T12:44:23.898007Z", "anonymous\_id": null, "archive": null, "poll": 31754, "person": 355244}"

---

<div class="post-metadata">

**Author:** ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)\
**Post date:** [12 June 2019 12:53 UTC](https://discourse.nodered.org/t/creating-percentages-from-responses/12097/14 "2019-06-12T12:53:00Z")

</div>

Note that that is a string, not a javascript object, which you did not tell us before. If you feed that through a JSON node it should convert it to a javascript object. Try that after looking at what the JSON node passes on and making sure it looks ok.

---

<div class="post-metadata">

**Author:** ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)\
**Post date:** [12 June 2019 12:53 UTC](https://discourse.nodered.org/t/creating-percentages-from-responses/12097/15 "2019-06-12T12:53:32Z")

</div>

> [@graphicsop](#):
>
> I selected the second option

What do you mean by that?

---

<div class="post-metadata">

**Author:** ![graphicsop](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/graphicsop/32/8663_2.png) [@graphicsop](https://discourse.nodered.org/u/graphicsop)\
**Post date:** [12 June 2019 13:00 UTC](https://discourse.nodered.org/t/creating-percentages-from-responses/12097/16 "2019-06-12T13:00:04Z")

</div>

Sorry.  
This is what came through after going through a JSON node -

object  
id: 484993  
content\_type: null  
object\_id: null  
response\_obj: object  
id: 227825  
pollresponse: 0x76681  
response: array[1]  
0: 42834  
response\_type: "choice"  
is\_active: true  
created: "2019-06-11T14:40:57.794723Z"  
updated: "2019-06-12T12:58:13.074971Z"  
anonymous\_id: null  
archive: null  
poll: 31754  
person: 355244

The source is a 4 option voting question, which is what I'm trying to aggregate the results from.  
This is the message I get when option 2 is selected.

---

<div class="post-metadata">

**Author:** ![graphicsop](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/graphicsop/32/8663_2.png) [@graphicsop](https://discourse.nodered.org/u/graphicsop)\
**Post date:** [12 June 2019 13:16 UTC](https://discourse.nodered.org/t/creating-percentages-from-responses/12097/17 "2019-06-12T13:16:05Z")

</div>

Apologies, I don't think I'm explaining myself very well.

My source is a multiple choice voting app that I need to capture each answer that comes through and display a number from 0-100 for each result.

The source app uses an Ably Realtime feed to broadcast when a user has selected an answer.  
This is coming into Node-RED as a MQTT feed.

Below is the source web app:

 ![Voting](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/2X/a/a1706ba8516da47e130d9d6f1baba3fb058f1f34.png)

When I select the second option and submit the following message comes through.

 ![Voting2](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/2X/d/d30bca318370b0d46d48decea08ccfc727b5d81e.png)

object  
id: 484993  
content\_type: null  
object\_id: null  
response\_obj: object  
id: 227825  
pollresponse: 0x76681  
response: array[1]  
0: 42836  
response\_type: "choice"  
is\_active: true  
created: "2019-06-11T14:40:57.794723Z"  
updated: "2019-06-12T13:15:06.381463Z"  
anonymous\_id: null  
archive: null  
poll: 31754  
person: 355244

Does that make more sense?

Many thanks  
Patrick

---

<div class="post-metadata">

**Author:** ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)\
**Post date:** [12 June 2019 13:37 UTC](https://discourse.nodered.org/t/creating-percentages-from-responses/12097/18 "2019-06-12T13:37:41Z")

</div>

The important thing is what is in the message, which now looks ok, so what now happens when you feed it into the function node?

---

<div class="post-metadata">

**Author:** ![graphicsop](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/graphicsop/32/8663_2.png) [@graphicsop](https://discourse.nodered.org/u/graphicsop)\
**Post date:** [12 June 2019 13:49 UTC](https://discourse.nodered.org/t/creating-percentages-from-responses/12097/19 "2019-06-12T13:49:21Z")

</div>

Below is what comes out of the Function node into the debug node.

object  
id: 484993  
content\_type: null  
object\_id: null  
response\_obj: object  
id: 227825  
pollresponse: 484993  
response: array[1]  
0: 42836  
response\_type: "choice"  
is\_active: true  
created: "2019-06-11T14:40:57.794723Z"  
updated: "2019-06-12T13:45:22.039299Z"  
anonymous\_id: null  
archive: null  
poll: 31754

It looks exactly the same as what comes out of the JSON node?

 ![Node-RED](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/2X/4/431de87f58a00c70de469e02c83d599ad5a3a275.png)

---

<div class="post-metadata">

**Author:** ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)\
**Post date:** [12 June 2019 14:18 UTC](https://discourse.nodered.org/t/creating-percentages-from-responses/12097/20 "2019-06-12T14:18:46Z")

</div>

Look carefully at the code in function node. Where does it save the results? Then change the debug node to 'Show Entire Message' and try again.

---

<div class="post-metadata">

**Author:** ![graphicsop](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/graphicsop/32/8663_2.png) [@graphicsop](https://discourse.nodered.org/u/graphicsop)\
**Post date:** [12 June 2019 14:31 UTC](https://discourse.nodered.org/t/creating-percentages-from-responses/12097/21 "2019-06-12T14:31:53Z")

</div>

Ah, yes thanks!  
I'm getting this now when I select all four options:

results: array[4]  
0: "25.00"  
1: "25.00"  
2: "25.00"  
3: "25.00"

Can I separate each result value and pipe into a separate OSC node?

[Next page](https://discourse.nodered.org/t/creating-percentages-from-responses/12097.md?page=2)
