AngularFire2 and Ionic2, calculating list sum - list

please help me to figure out how to calculate a sum of objects values coming from firebase using AngularFire2 in ionic.
I am trying do this way:
in the HTML file i want call the function:
<ion-col col-1>
{{(calculateAverage(student.$key) | async)}}
</ion-col>
In the .ts file i want to do something like this, get the list of objects, iterate over it and sum the values of a child and return that value to the html.
i know how to use this.af.database.list to get a list and show values in the HTML using the *ngFor, but not know how to iterate in the .ts file and return a value to the HTML, cause this is async.
Example of firebase data:
"-KhdUCJAyr7Y4Zz3QOnl" : {
"-KigSgGlWyFQao80DuA0" : {
"value" : "30"
},
"-KigTDI3Nue88If0fdYl" : {
"value" : "70"
}
}
Can anyong help me please?
Thanks in Advance.

You can do the calculate in subscribe of this.af.database.list.
// suppose you keep the observable
this.items = this.af.database.list('/sample');
// do calculate in observable.subscribe
this.items.subscribe(data => {
data.forEach(item => {
// sum here
calculateSum(item.value);
});
// calculate average here
calculateAverage();
});
example of how to calculate and show in templete:
sumValue = 0;
averageValue = 0;
// sum values
calculateSum(value) {
this.sumValue = this.sumValue + parseInt(value);
}
calculateAverage(count) {
this.averageValue = this.sumValue / count;
}
display result of calculate in template:
<span>averageValue</span>

Related

Google Script Run Function IF text in another sheet's column contains a 'specific text'

I've done extensive search for this, but none of them seems to work. They all just give me a blank sheet.
Sample sheet
Basically I have a function that extracts data from Col. B in DATA, to Result. Then does some other things, split, trim etc...
I want to run this function when the text in Col. A in DATA is 250P.
So it would be like: IF (DATA!A1:A contains text "250p" then run function EXTRACT).
This is the code I have as of now:
//this extract works fine but I just need this to work for only those with value 250 in Col A//
function EXTRACT() {
var spreadsheet = SpreadsheetApp.getActive();
spreadsheet.getRange('A1').setFormula('=EXTRACTDATA(DATA!A1:A)');
}
function IF250() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('DATA');
var range = sheet.getRange('DATA!A1:A');
var values = range.getValues();
if (values[i] == "250g") {
EXTRACT();
Better yet, If I can have the data set in 2 separate sheets. The 250s in one sheet & 500s in one sheet. But this is not necessary.
After reviewing your sheet, this is a possible solution
Code.gs
const sS = SpreadsheetApp.getActiveSpreadsheet()
function grabData() {
const sheetIn = sS.getSheetByName('data')
const sheetOut = sS.getSheetByName('Desired Outcome')
const range = 'A2:B'
/* Grab all the data from columns A and B and filter it */
const values = sheetIn.getRange(range).getValues().filter(n => n[0])
/* Retrieve only the names if it containes 250p */
/* In format [[a], [b], ...] */
const parsedValues = values.map((arr) => {
const [type, name] = arr
if (type.toLowerCase().includes('250p')) {
return name.split('\n')
}
})
.filter(n => n)
.flat()
.map(n => [n])
/* Add the values to the Desired Outcome Sheet */
sheetOut
.getRange(sheetOut.getLastRow() + 1, 1, parsedValues.length)
.setValues(parsedValues)
}
Try changing:
var values = range.getValues();
to
var values = range.getDisplayValues()
As this will read the value that is shown. Try logging the values with both to see why! (Blank)
You are also not currently iterating, or looping, your values.
If you're just looking to see if the column contains a cell containing the value 250p, try:
function IF250() {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(`DATA`)
const valueExists = sheet.getRange(`A1:A`)
.getDisplayValues()
.filter(String)
.some(row => row.includes(`250P`))
if (valueExists) EXTRACT()
}
Commented:
function IF250() {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(`DATA`)
const valueExists = sheet.getRange(`A1:A`)
.getDisplayValues()
// Remove empty cells (not strictly necessary)
.filter(String)
// If the values include a row containing `250p` return true.
.some(row => row.includes(`250P`))
// If valueExists returns true:
if (valueExists) EXTRACT()
}

How to count elements inside array in Postman test

I was unable to find correct answer and therefore posting a question.
Return response on Postman is as below:
[
{
"AttemptNumber":1,
"LoginID":test123,
"CurrentStatus":2
}
]
I'm trying to count elements in this array object.
this is what I was doing:
countItems = JSON.pase(responseBody)
for (var i = 1, l = Object.keys(countItems).length; i <=3){
}
but I keep getting 1. 1 is array but I'm looking for count to be 3.
I'll appreciate your expertise.
Thanks.
This should log the number of items from each object in the response array:
let res = pm.response.json()
_.each(res, (obj) => {
console.log(_.keys(obj).length)
})
It's using some methods from Lodash, which is one of the built-in libraries.
https://lodash.com/docs/4.17.15

Flutter/Dart: How to get list value where key equals

I'm not sure why I'm having such a hard time finding an answer for this, but I have a list that I need to get the value from where the key matches certain criteria. The keys are all unique. In the example below, I want to get the color where the name equals "headache". Result should be "4294930176".
//Example list
String trendName = 'headache';
List trendsList = [{name: fatigue, color: 4284513675}, {name: headache, color: 4294930176}];
//What I'm trying
int trendIndex = trendsList.indexWhere((f) => f.name == trendName);
Color trendColor = Color(int.parse(trendsList[trendIndex].color));
print(trendColor);
Error I get: Class '_InternalLinkedHashMap' has no instance getter 'name'. Any suggestions?
EDIT:
Here's how I'm adding the data to the list, where userDocuments is taken from a Firestore collection:
for (int i = 0; i < userDocument.length; i++) {
var trendColorMap = {
'name': userDocument[i]['name'],
'color': userDocument[i]['color'].toString(),
};
trendsList.add(trendColorMap);
}
I guess, I got what the problem was. You were making a little mistake, and that was, you're trying to call the Map element as an object value.
A HashMap element cannot be called as f.name, it has to be called f['name']. So taking your code as a reference, do this, and you are good to go.
String trendName = 'headache';
List trendsList = [{'name': 'fatigue', 'color': 4284513675}, {'name': headache, 'color': 4294930176}];
//What I'm trying
// You call the name as f['name']
int trendIndex = trendsList.indexWhere((f) => f['name'] == trendName);
print(trendIndex) // Output you will get is 1
Color trendColor = Color(int.parse(trendsList[trendIndex]['color'])); //same with this ['color'] not x.color
print(trendColor);
Check that out, and let me know if that helps you, I am sure it will :)

SuiteScript 2.0 Map Reduce Script Complete Sample

I was hit SSS USAGE LIMIT EXCEEDED error in Netsuite.
I plan to change the search to use Map Reduce Script, however, I didn't found any complete example to call Map Reduce Script, like how to pass parameter to Map Reduce Script and get the resultset from it. Would you please show me how? Thanks in advance
the below show how to define the task to call Map Reduce Script
SuiteScript 2.0 UserEvent Script to Call Map Reduce
define(['N/record', 'N/log', 'N/Task'],
function (record, log, task) {
function setFieldInRecord (scriptContext) {
log.debug({
'title': 'TESTING',
'details': 'WE ARE IN THE FUNCTION!'
});
if (scriptContext.type === scriptContext.UserEventType.EDIT) {
var scriptTask = task.create({
taskType: task.TaskType.MAP_REDUCE
});
scriptTask.scriptId = 'customscript_id';
scriptTask.deploymentId = 'customdeploy_id';
var scriptTaskId = scriptTask.submit();
//How to pass parameter to getInputData?
//How to get the result?
}
}
return {
beforeSubmit: setFieldInRecord
};
}
);
Map/Reduce script type provides you with 4 entry point functions to load/process your data:
getInputData(inputContext)
map(mapContext)
reduce(reduceContext)
summarize(summaryContext)
Example:
function summarize(context) {
context.output.iterator().each(function(key, value) {
// your logic here
return true;
});
}
Take a look at this help center section, there are examples (only available with NetSuite account):
https://system.netsuite.com/app/help/helpcenter.nl?fid=section_4387799161.html

How can I scale my dataset values as a percentage of the index in chart.js?

Sorry if the question is poorly worded.Here is my chart
I am looking into scaling the chart's display of dataset(s) values as a percentage such as:
//input
data:{
datasets[{
label: 'data1',
data: [15, 22, 18, 35, 16, 29, 40]
},
{
label: 'data2',
data: [20, 21, 20, 19, 21, 22, 35]
}]
data1's points on the chart would be displayed as [42.9, 51.2, 47.4, 64.8, 43.2, 56.9, 57.1]
data2's points on the chart would be displayed as [57.1, 48.8, 52.6, 35.2, 56.8, 43.1, 42.9]
It should look like this. All visible lines should stack up to 100%. If a dataset is hidden, how can I recalculate the percentage and update the chart so that everything stays stacked up to 100%?
I thought about doing a plugin where I do the calculation using myLine.data.datasets but then I don't know how to remove a hidden dataset's values from the calculation and I'm not sure how to display it unless I overwrite the original datasets. I'm pretty sure this is the wrong approach.
Any help would be greatly appreciated.
So, I figured it out. I needed to write a function to calculate the percentage area of the points in the index and then update the datasets with the calculated percentage values.
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
*
* DS_update calculates the percentage area of the input datasets
*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
function DS_update(dataset_in, ds_vis){
// make a deep copy (no references to the source)
var temp = jQuery.extend(true, [], dataset_in);
// gets the sum of all datasets at a given index
function getTotal(index){
total = 0;
// step through the datasets
dataset_in.forEach(function(e, i){
// inc total if the dataset is visible
if(ds_vis[i]){
total += e[index];
}
// do nothing if the dataset is hidden
});
return total;
}
// update temp array with calculated percentage values
temp.forEach(function(el, ind){
var j = ind;
el.forEach(function(e, i){
// calculate percentage to the hundredths place
temp[j][i] = Math.round((e / getTotal(i))*10000)/100;
});
});
return temp;
}
Once I tested the functions I had to run them before initial load of the chart or else the user would see the datasets as non area-percent (raw data). which looks something like this:
// Keep source array to use in the tool tips
var Src_ary = Input_data; // multidimensional array of input data
// holds the percent-area calculations as datapoints
var Prod_ary = DS_update(Src_ary, Init_visible(Src_ary));
Next up was updating the onClick for the legend. I need this to update the calculations every time an item's visibility is toggled:
legend: {
position: 'bottom',
usePointStyle: true,
onClick:
function(e, legendItem){
var index = legendItem.datasetIndex;
var ci = this.chart;
var meta = ci.getDatasetMeta(index);
var vis_ary = [];
var updatedSet = [];
// See controller.isDatasetVisible comment
meta.hidden = meta.hidden === null? !ci.data.datasets[index].hidden : null;
// load the visible array
for(var i = 0; i < (ci.data.datasets || []).length; i++){
switch (ci.getDatasetMeta(i).hidden){
case null:
vis_ary.push(true);
break;
default:
vis_ary.push(false);
break;
}
}
// update datasets using vis_ary to tell us which sets are visible
updatedSet = DS_update(Prod_ary, vis_ary);
myLine.data.datasets.forEach(function (e,i){
e.data = updatedSet[i];
});
// We did stuff ... rerender the chart
ci.update();
}
}
END RESULT
This is what I was trying to do: highchart fiddle
This is what I ended up with:fiddle
It took a few days and a lot of reading through chartjs.org's documentation to put this together. In the end I think it came out pretty good considering I am new to chart.js and borderline illiterate with javascript.