Add elements from array to object to format fusionchart data - javascript

I want to format the data of my fusion chart based on scope variable.
I have a function which gets dates and stock values assigned to this dates.
So I have 2 arrays:
dates = [2017-04-28, 2017-04-27, 2017-04-26, 2017-04-25]
stockValues = [150.25, 147.7, 146.56, 146.49]
What I want to do is to create a new object which looks like this:
data: [{
"label": "2017-04-28",
"value": "150.25"
},
{
"label": "2017-04-27",
"value": "147.7"
},
... //and so on
]
I managed to come up with following code:
$scope.getStockData = function(stockID) {
$http.get('/stock', {
params : {
stockID : encodeURI(stockID)
}
}).then(function(response) {
$scope.stock = response.data;
var data={};
$scope.data={};
angular.forEach(response.data.dates,function(value){
data["label"] = value;
})
angular.forEach(response.data.stockValues,function(value){
data["value"] = value;
})
$scope.data = data;
}, function(response) {
$scope.showError = true;
}).finally(function() {
});
};
The problem is that this solution creates object which looks like this:
{"label":"2017-04-25","value":"146.49"}
So it takes only the last values from array.
How can I make my object look the way I want it to?

Example:
const dates = ['2017-04-28', '2017-04-27', '2017-04-26', '2017-04-25']
const stockValues = ['150.25', '147.7', '146.56', '146.49']
const r = dates.map((d, i) => Object.assign({
label: d,
value: stockValues[i]
}))
console.log(JSON.stringify(r, null, 2))

Try this, you must initialize an array, and the push at the right location.
$scope.getStockData = function(stockID) {
$http.get('/stock', {
params : {
stockID : encodeURI(stockID)
}
}).then(function(response) {
$scope.stock = response.data;
var data=[];
$scope.data=[];
angular.forEach(response.data.dates,function(value, i){
data[i]["label"] = value;
})
angular.forEach(response.data.stockValues,function(value, i){
data[i]["value"] = value;
})
$scope.data = data;
}, function(response) {
$scope.showError = true;
}).finally(function() {
});
};

Related

JavaScript - Targeting an object value to create another variable

So I have an array which looks like this:
[
{ TransactionValues: '50.00' },
{ TransactionValues: '-77.43' },
{ TransactionValues: '-20.23' },
{ TransactionValues: '200.23' }
]
I am trying to find a way to target the monetary value and create a variable based on the sum of these. When I try to target the "50.00" for example I get "Undefined" and it's still an array.
I'm not exactly sure how I can target it specifically, is it possible? Any help would be appreciated
As per the comments here is the full code (be wary I'm still learning so it's not elegant):
var fs = require('fs');
var parse = require('csv-parse');
var transactionValues = []; //Need an array to hold transactions
var currentTrans = [];
var savingsTrans = [];
//constuctor for transactions
function addData (id, accountType, initiatorType, dateTime, transactions) {
var data = {
"AccountID" : id,
"AccountType" : accountType,
"InitiatorType" : initiatorType,
"DateTime" : dateTime,
"TransactionValues" : transactions
}
transactionValues.push(data); //should add a new line
}
function logTrans (accountType, transactions) {
if (accountType == "CURRENT") {
var cTrans = {
"TransactionValues" : transactions
}
currentTrans.push(cTrans);
}
else {
var sTrans = {
"TransactionValues" : transactions
}
savingsTrans.push(sTrans);
}
};
//parses the csv file, loops each row and adds it to the transactionValue array
var parser = parse({columns: true}, function (err, results) {
console.table(results);
for (const row of results) {
addData(row.AccountID, row.AccountType, row.InitiatorType, row.DateTime, row.TransactionValue );
logTrans(row.AccountType, row.TransactionValue);
}
console.log(transactionValues);
console.log(currentTrans);
console.log(savingsTrans);
});
fs.createReadStream(__dirname+'/testData/customer-1234567-ledger.csv').pipe(parser)
not completely following but at the end of the day you have an array like data below.
you can use filter to target the attribute you want.
you can use map to pull out just the values.
you can use reduce to sum them all up.
run the snippet below to see each step
const data = [
{ TransactionValues: '50.00', AccountType: 'CURRENT' },
{ TransactionValues: '-77.43', AccountType: null},
{ TransactionValues: '-20.23', AccountType: 'CURRENT' },
{ TransactionValues: '200.23', AccountType: null }
];
const CurrentTrans = data.filter((x) => x.AccountType === 'CURRENT');
const SavingTrans = data.filter((x) => x.AccountType !== 'CURRENT');
console.log('CurrentTrans');
console.log(CurrentTrans);
console.log('SavingTrans');
console.log(SavingTrans);
const CurrentTransValues = CurrentTrans.map((x) => parseFloat(x.TransactionValues));
const SavingTransValues = SavingTrans.map((x) => parseFloat(x.TransactionValues));
console.log('CurrentTransValues');
console.log(CurrentTransValues);
console.log('SavingTransValues');
console.log(SavingTransValues);
const TotalCurrentValues = CurrentTransValues.reduce((sum, x) => sum + x);
const TotalSavingValues = SavingTransValues.reduce((sum, x) => sum + x);
console.log('TotalCurrentValues');
console.log(TotalCurrentValues.toFixed(2));
console.log('TotalSavingValues');
console.log(TotalSavingValues.toFixed(2));
So I may have fixed it by using parseFloat in my addData and logTrans functions:
function addData (id, accountType, initiatorType, dateTime, transactions) {
var data = {
"AccountID" : id,
"AccountType" : accountType,
"InitiatorType" : initiatorType,
"DateTime" : dateTime,
"TransactionValues" : parseFloat(transactions)
}
transactionValues.push(data); //should add a new line
}
function logTrans (accountType, transactions) {
if (accountType == "CURRENT") {
var cTrans = parseFloat(transactions);
currentTrans.push(cTrans);
}
else {
var sTrans = parseFloat(transactions);
savingsTrans.push(sTrans);
}
};
Now that seems to of worked. So I can use the "Sum values of objects in array" as suggested before. Thank you everyone :)

How to search a single cell with multiple values

I'm trying to search a JSON. Right now it functions with an exact match. I want to add multiple data to one cell - it'll look like this: "data, data2, nope, nope2". If a user searches 'data' it needs to match for data and data2.
this is the json:
[
{"car":"Mercedes, Toyota, KIA", "state":"SA", "groupName":"AHG"},
{"car":"BMW","state":"NSW","groupName":"Brighton BMW"},
{"car":"Tesla","state":"VIC","groupName":"JAMES F"},
{"car":"Audi","state":"WA","groupName":"Audi CBD","groupPhone":"1300 04"},
{"car":"Mercedes","state":"SA","groupName":"AHG","groupPhone":"1300 05"}
]
eg the 1st string of- "car":"Mercedes, Toyota, KIA" I need to return results if a user searches for Toyota. Right now it only works if the string is only "car":"Toyota"
var app = new Vue({
el: '#app',
data: {
addCar: false,
cars: [],
loading: false,
searchCar: "",
searchState: ""
},
methods: {
search: function () {
app.loading = true;
var searchQuery = {
car: encodeURIComponent(app.searchCar)
};
if (app.searchState) {
searchQuery.state = app.searchState;
};
Sheetsu.read("https://sheetsu.com/apis/v1.0su/a4d7192e71fd", {
search: searchQuery
}).then(function (data) {
console.log(data);
app.cars = data;
app.loading = false;
},
function (err) {
console.log(err);
app.cars = [];
app.loading = false;
});
},
}
})
Would be amazing if a user can search for Toyota and be delivered results for any string containing Toyota as a car :)
Simple client-side search can be implemented by passing a regular expression object to the String#match method, where the pattern of the regular expression is your query/search string:
/* Returns non-null result is "query" matches any part of item.car string */
return item.car.match(new RegExp(query, "gi"))
You could combine this with Array#filter() to aquire only items for your JSON where the car field contains the query string:
const json = [
{"car":"Mercedes, Toyota, KIA", "state":"SA", "groupName":"AHG"},
{"car":"BMW","state":"NSW","groupName":"Brighton BMW"},
{"car":"Tesla","state":"VIC","groupName":"JAMES F"},
{"car":"Audi","state":"WA","groupName":"Audi CBD","groupPhone":"1300 04"},
{"car":"Mercedes","state":"SA","groupName":"AHG","groupPhone":"1300 05"}
]
const findItem = (data, query) => {
return data.filter(item => {
return item.car.match(new RegExp(query, "gi"))
});
}
console.log("Search for Toyota", findItem(json, "Toyota"));
console.log("Search for Mercedes", findItem(json, "Mercedes"));
console.log("Search for Tesla", findItem(json, "Tesla"));
console.log("Search for Honda", findItem(json, "Honda"));
Update
To integrate the code snippet shown above with your Vue component, try this:
var app = new Vue({
el: '#app',
data: {
addCar: false,
cars: [],
loading: false,
searchCar: "",
searchState: ""
},
methods: {
search: function() {
app.loading = true;
var searchQuery = {
car: encodeURIComponent(app.searchCar)
};
if (app.searchState) {
searchQuery.state = app.searchState;
};
Sheetsu.read("https://sheetsu.com/apis/v1.0su/a4d7192e71fd", {
search: searchQuery
}).then(function(data) {
/*
Add code here
*/
data = data.filter(item => {
return item.car.match(new RegExp(app.searchCar, "gi"))
});
app.cars = data;
app.loading = false;
},
function(err) {
console.log(err);
app.cars = [];
app.loading = false;
});
},
}
})
You can use filter and includes
let arr = [{"car":"Mercedes, Toyota, KIA", "state":"SA", "groupName":"AHG"},{"car":"BMW","state":"NSW","groupName":"Brighton BMW"},{"car":"Tesla","state":"VIC","groupName":"JAMES F"},{"car":"Audi","state":"WA","groupName":"Audi CBD","groupPhone":"1300 04"},{"car":"Mercedes","state":"SA","groupName":"AHG","groupPhone":"1300 05"},{"car":"Toyota, Testing function", "state":"SA", "groupName":"AHG"}]
let selectedKey = 'car'
let selectedValue = 'Toyota'
let op = arr.filter(({[selectedKey]:key})=> key && key.includes(selectedValue))
console.log(op)

Javascript push array inside object

How do I create the data array from my second api call result into the format I want?
I have a code like this
var github = require('octonode');
var client = github.client();
var userName = "octocat";
var repoName = "";
var branchName = "";
var data = [];
var branches = [];
client.get('/users/'+userName+'/repos', {}, function (err, status, body, headers) {
body.forEach(function(obj) {
repoName = obj.name;
//==============================
client.get('repos/'+userName+'/'+repoName+'/branches', {}, function (errx, statusx, bodyChild, headersx) {
bodyChild.forEach(function(objChild) {
branchName = objChild.name;
});
});
});
});
I have received repoName and branchName data as well.
I want my data format like
How to use
data.push({
name: repoName,
branches: 'branchName loooping here for every repoName'
});
so branches repetition data can be contained in my branches tag
Thank you
I guess you can do something like this:
var data = [];
client.get('/users/'+userName+'/repos', {}, function (err, status, body, headers) {
body.forEach(function(obj) {
repoName = obj.name;
client.get('repos/'+userName+'/'+repoName+'/branches', {}, function (errx, statusx, bodyChild, headersx) {
let elem = {"name": repoName, "branches": []}; //create json object for each repo
bodyChild.forEach(function(objChild) {
elem.branches.push(objChild.name); //push all branchs to that elem
});
data.push(elem); // add the elem to the data array
});
});
});
So in this case data is an object, that has a property name which is string, and another property branches which is array. If you want to push data to the property branches you can just call the push() function on it.
Please check the example below:
let data = {
name: "repoName",
branches: [
{
name: "foo"
}
]
}
data.branches.push(
{
name: "bar"
}
);
console.log(data);

associative array : cannot set property of undefined

I have to retrieve the data from a JSON file then assign it to an array. But I am getting an error
"Cannot set property 'ref' of undefined".
Converting JSON to associative arrays or objects.
var items2=[[]];
$.getJSON("results.json", function( data ) {
$.each( data, function( key, val ) {
if(key=="items")
{
$.each(val,function(keyScd,valScd)
{
$.each(valScd,function(keyTrd,valTrd)
{
var ref=JSON.stringify(valTrd.ref).slice(1,-1);
var prix=JSON.stringify(valTrd.prix).slice(1,-1);
var taille=JSON.stringify(valTrd.taille).slice(1,-1);
items2[keyScd][keyTrd]["ref"]=ref;
items2[keyScd][keyTrd]["prix"]=prix;
items2[keyScd][keyTrd]["taille"]=taille;
});
});
}
else
{
items2[key]=val;
}
});
});
and here is my JSON
{
"items":[
[
{
"ref":"cpe-zfmmpx23",
"nomc":"1",
"description":"yellow sofa",
"dispo":"1",
"prix":"300",
"taille":"standard",
"couleur":"jaune"
},
{
"ref":"cpe-zfmmpx23",
"nomc":"2",
"description":"yellow sofa",
"dispo":"1",
"prix":"400",
"taille":"0.5mH,2mW",
"couleur":"red"
}
]
],
"buildNumber":"fa36b5153f33240a111e6dc336a70"
}
You should just be able to map the elements. Is this what you are after?
var temp = `{"items":[[{"ref":"cpe-zfmmpx23","nomc":"1","description":"yellow sofa","dispo":"1","prix":"300","taille":"standard","couleur":"jaune"},{"ref":"cpe-zfmmpx23","nomc":"2","description":"yellow sofa","dispo":"1","prix":"400","taille":"0.5mH,2mW","couleur":"red"}]],"buildNumber":"fa36b5153f33240a111e6dc336a70"}
`;
var data = JSON.parse(temp);
var items2;
if (data.items) {
items2 = $.map(data.items, function(items) {
return $.map(items, function(item) {
return {
ref: item.ref.slice(1, -1),
prix: item.prix.slice(1, -1),
taille: item.taille.slice(1, -1)
};
});
});
}
console.log(items2);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Here is another way to do it, no need for jquery there :
const json = '{"items":[[{"ref":"cpe-zfmmpx23","nomc":"1","description":"yellow sofa","dispo":"1","prix":"300","taille":"standard","couleur":"jaune"},{"ref":"cpe-zfmmpx23","nomc":"2","description":"yellow sofa","dispo":"1","prix":"400","taille":"0.5mH,2mW","couleur":"red"}]],"buildNumber":"fa36b5153f33240a111e6dc336a70"}';
const newJson = JSON.parse(json);
(newJson.items).forEach((data) => {
data.forEach((newData) => {
console.log(newData.ref)
});
});

printing all records using only one alert

I have the following code with the JSFiddle for the same here:
var result = [
{"Id": 10004, "PageName": "club"},
{"Id": 10040, "PageName": "qaz"},
{"Id": 10059, "PageName": "jjjjjjj"}
];
$.each(result, function(i, item) {
alert(result[i].PageName);
});
In order to see all the results, I have to click Ok in alert window two times. How can I display the contents using one alert only?
//f1.js ---
var PatientReviewPage = (function () {
var cls = function () { }
var self = cls.prototype;
self.urlKey = "showmrn";
self.getData = function (mrn_) {
/*
if (isEmpty(mrn_)) { alert("Invalid mrn in getData()"); return false; }
// Lookup the AJAX web service URL
var url = regman.getWebServiceURL(self.urlKey);
if (isEmpty(url)) { alert("Invalid URL in getData()"); return false; }
var ajaxRequest = jQuery.ajax({
//beforeSend: TODO: show spinner!
data: {
registry_id: regman.registry.id,
mrn: mrn_
},
dataType: "json",
method: "GET",
url: url
})*/
//Some code related to ajax reques
this.done(function (data_, textStatus_, jqXHR_) {
// Validate the web service and retrieve the status.
if (typeof (data_) === "undefined" || data_ === null) {
alert("Invalid data returned from web service");
return false;
}
if (isEmpty(data_.webservice_status) || isEmpty(data_.webservice_status.status)) {
alert("Invalid web service status");
return false;
}
if (data_.webservice_status.status != "SUCCESS") {
alert(data_.webservice_status.message);
return false;
}
self.processdataDocuments(data_.data_document_list);
});
this.fail(function (jqXHR_, textStatus_, errorThrown_) {
alert("Error in getData(): " + errorThrown_);
return false;
});
};
// Initialize the page
self.initialize = function () {
var mrn = regman.selectedData["mrn"];
if (isEmpty(mrn)) {
alert("Invalid MRN provided by calling page");
return false;
}
self.getData(mrn);
};
self.processdataDocuments = function (collection_) {
if (isEmpty(collection_) || collection_.length < 1) {
// Populate the count and exit
jQuery("#nlpDocumentCount").html("(0)");
return true;
}
var source =
{
localdata: collection_,
datatype: "array"
};
var dataAdapter = new $.jqx.dataAdapter(source, {
loadComplete: function (data) { },
loadError: function (xhr, status, error) { }
});
$("#nlpDocumentPanel").jqxGrid(
{
source: dataAdapter,
width: '1000',
height: 150,
columns: [
{
text: 'Type', datafield: 'nc_type'
},
{
text: 'SubType', datafield: 'nc_subtype'
},
{
text: 'Concept', datafield: 'concept_text'
},
{
text: 'Date', datafield: 'nc_dos'
}
]
});
// For getting the contents of a row, I am using jqxgrid approach as mentioned in their doc here :
// http://www.jqwidgets.com/getting-the-clicked-grid-row/
$("#nlpDocumentPanel").on('rowclick', function (event) {
var row = event.args.rowindex;
var datarow = $("#nlpDocumentPanel").jqxGrid('getrowdata', row);
response = JSON.stringify(datarow, null, 10)
//alert(jsonStringify); // This alert displays the JSON data in a formatted manner
var obj = jQuery.parseJSON(response);
//alert("display Subtype "+obj.nc_subtype) // Works fine
self.mySubtype = obj.nc_subtype;
});
};
//I added this line for the demo to show 'f2' accessing this property from 'f1'. You should remove it if copying this code into your application
self.mySubtype = "Foo";
return cls;
})();
var f1 = new PatientReviewPage();
//f2.js ---
var DocumentDetailsDialog = (function () {
var cls = function () { }
var self = cls.prototype;
alert(f1.mySubtype);
/*this.getData = function (IDNumber_) {
// some code will be here
var ajaxRequest = jQuery.ajax({
// some code will be here
})
.done(function (data_, textStatus_, jqXHR_) {
// some code will be here
})
.fail(function (jqXHR_, textStatus_, errorThrown_) {
// some code will be here
});
};*/
return cls;
})();
var f2 = new DocumentDetailsDialog();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
You can use map() and join() and return string with page names.
var result = [
{"Id": 10004, "PageName": "club"},
{"Id": 10040, "PageName": "qaz"},
{"Id": 10059, "PageName": "jjjjjjj"}
];
var r = result.map(function(e) {
return e.PageName;
}).join(' ');
alert(r);
Build a string with the results and alert the string:
alert(result.map( _ => _.PageName).join(', '))

Categories

Resources