I want to convert an array of objects into CSV.
Please have a look at the code. What I am doing wrong? I am getting an array when I console.log("csv",array) which is passed from printAccountsGa. Moreover, I have declared JSONGA = [] globally but still I get array with every object on consoling. But when I pass that to csvConverter function it displays undefined.
function printAccountsGa(results) {
if (results && !results.error) {
var accounts = results.items;
for (var i = 0, account; account = accounts[i]; i++) {
//console.log('Account Id: ' + account.id);
listProperties(account.id);
//console.log('Account Name: ' + account.name);
}
console.log(JSONGA);
csvConverter(JSONGA);
}
}
function printAccountsGtm(results) {
console.log("result is",results);
if (results && !results.error) {
var accounts = results.accounts;
console.log(accounts);
for (var i = 0, account; account = accounts[i]; i++) {
//console.log('Account Id: ' + account.accountId);
listContainers(account.accountId);
//console.log('Account Name: ' + account.name);
}
}
}
function listProperties(accountID){
var request = gapi.client.analytics.management.webproperties.list({
'accountId': accountID
});
request.execute(printProperties);
}
function printProperties(results){
if (results && !results.error) {
var properties = results.items;
//console.log(properties[0].accountId);
$.each(properties,function(element){
//console.log(properties[element].accountId);
var tempObj={};
tempObj={
'AccountID':properties[element].accountId,
'PropertyID':properties[element].id,
'name':properties[element].name,
}
JSONGA.push(tempObj);
})
}
}
function csvConverter(array){
console.log("csv",array);
var result = array.map(function(d){
return JSON.stringify(values(d));
})
.join('\n')
.replace(/(^\[)|(\]$)/mg, '');
window.open('data:text/csv;charset=utf-8,' + escape(result));
}
window.onload = function(){
var el = document.getElementById('auth-button-ga');
el.addEventListener('click', authorizeGa);
var elt = document.getElementById("auth-button-gtm");
elt.addEventListener('click', authorizeGtm);
}
Related
I've done some searching around the web and nothing seems to solve my problem. I have the following jQuery code:
function youtube_data_parser(data) {
//---> parse video data - start
var qsToJson = function(qs) {
var res = {};
var pars = qs.split('&');
var kv, k, v;
for (i in pars) {
kv = pars[i].split('=');
k = kv[0];
v = kv[1];
res[k] = decodeURIComponent(v);
}
return res;
}
//---> parse video data - end
var get_video_info = qsToJson(data);
if (get_video_info.status == 'fail') {
return {
status: "error",
code: "invalid_url",
msg: "check your url or video id"
};
} else {
// remapping urls into an array of objects
//--->parse > url_encoded_fmt_stream_map > start
//will get the video urls
var tmp = get_video_info["url_encoded_fmt_stream_map"];
if (tmp) {
tmp = tmp.split(',');
for (i in tmp) {
tmp[i] = qsToJson(tmp[i]);
}
get_video_info["url_encoded_fmt_stream_map"] = tmp;
}
//--->parse > url_encoded_fmt_stream_map > end
//--->parse > player_response > start
var tmp1 = get_video_info["player_response"];
if (tmp1) {
get_video_info["player_response"] = JSON.parse(tmp1);
}
//--->parse > player_response > end
//--->parse > keywords > start
var keywords = get_video_info["keywords"];
if (keywords) {
key_words = keywords.replace(/\+/g, ' ').split(',');
for (i in key_words) {
keywords[i] = qsToJson(key_words[i]);
}
get_video_info["keywords"] = {
all: keywords.replace(/\+/g, ' '),
arr: key_words
};
}
//--->parse > keywords > end
//return data
return {
status: 'success',
raw_data: qsToJson(data),
video_info: get_video_info
};
}
}
function getVideoInfo() {
var get_video_url = $('#ytdlUrl').val();
var get_video_id = getUrlVars(get_video_url)['v'];
var video_arr_final = [];
var ajax_url = "video_info.php?id=" + get_video_id;
$.get(ajax_url, function(d1) {
var data = youtube_data_parser(d1);
var video_data = data.video_info;
var player_info = data.video_info.player_response;
var video_title = player_info.videoDetails.title.replace(/\+/g, ' ');
var fmt_list = video_data.fmt_list.split(',');
var video_thumbnail_url = video_data.thumbnail_url;
var video_arr = video_data.url_encoded_fmt_stream_map;
//create video file array
$.each(video_arr, function(i1, v1) {
var valueToPush = {};
valueToPush.video_url = v1.url;
valueToPush.video_thumbnail_url = video_thumbnail_url;
valueToPush.video_title = video_title;
$.each(fmt_list, function(i2, v2) {
var fmt = v2.split('/');
var fmt_id = fmt[0];
var fmt_quality = fmt[1];
if (fmt_id == v1.itag) {
valueToPush.fmt_id = fmt_id;
valueToPush.fmt_quality = fmt_quality;
}
});
video_arr_final.push(valueToPush);
});
});
return video_arr_final;
}
function getUrlVars(url) {
var vars = {};
var parts = url.replace(/[?&]+([^=&]+)=([^&]*)/gi, function(m, key, value) {
vars[key] = value;
});
return vars;
}
function fillInOptions(ytOptions) {
//console.log(ytOptions);
//alert(ytOptions[0]);
var ytFill = ytOptions;
console.log(ytFill);
//ytFill.forEach(function(i,v) {
var ytdlOptions = $('#ytdlOptions');
ytFill.forEach(function(i,v) {
console.log(i);
ytdlOptions.append(new Option(v.fmt_quality, v.fmt_id));
});
return true;
}
function showYTDLLoader() {
$('#ytdlInput').fadeOut(1000, function() {
$('#ytdlLoader').fadeIn(500);
});
var options = getVideoInfo();
//console.log(options);
if (fillInOptions(options) == true) {
//do rest
}
}
function showYTDLOptions() {
return true;
}
function startDownload() {
showYTDLLoader();
}
function hideYTDLLoader() {
$('#ytdlLoader').fadeOut(500);
}
function animateCSS(element, animationName, callback) {
const node = $(element);
node.addClass(animationName);
function handleAnimationEnd() {
node.removeClass(animationName);
node.animationend = null;
if (typeof callback === 'function') callback();
}
node.animationend = handleAnimationEnd();
}
When my button is clicked, I call showYTDLLoader() which gets an array of objects from the YouTube API that looks like this:
[
{
"video_url": "https://r7---sn-uxanug5-cox6.googlevideo.com/videoplayback?expire=1572496003&ei=Iw66Xa24H8PL3LUPiN25mAs&ip=2001%3A8003%3A749b%3Aa01%3A5cd8%3Ac610%3A6402%3Ad0fe&id=o-ADsVnoOoBQ6-SWzYZU7gHES06s7xQptJG6hn9WcakITY&itag=22&source=youtube&requiressl=yes&mm=31%2C29&mn=sn-uxanug5-cox6%2Csn-ntqe6n7r&ms=au%2Crdu&mv=m&mvi=6&pl=39&initcwndbps=1655000&mime=video%2Fmp4&ratebypass=yes&dur=917.768&lmt=1572418007364260&mt=1572474311&fvip=4&fexp=23842630&c=WEB&txp=5535432&sparams=expire%2Cei%2Cip%2Cid%2Citag%2Csource%2Crequiressl%2Cmime%2Cratebypass%2Cdur%2Clmt&sig=ALgxI2wwRgIhAIp-4gyUTLoXFetbY0ha_YnR7DJqsp_MNjjIxqDdfPZJAiEA_WPd21jgX9broBcigf8rcSEVoJb2_NX7t3XZQqytsSM%3D&lsparams=mm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpl%2Cinitcwndbps&lsig=AHylml4wRAIgacvP3zjEq-rVEZFrX7a_hC6TR-Zab7Ii-Fbaupjs_PcCIHdZht4l4ioYL3ERz7WNiSbnOnhm5iYxEECaQXPP2hUp",
"video_title": "Arnold Schwarzenegger on Son-in-law Chris Pratt, Pranking Sylvester Stallone & Terminator’s Return",
"fmt_id": "22",
"fmt_quality": "1280x720"
},
{
"video_url": "https://r7---sn-uxanug5-cox6.googlevideo.com/videoplayback?expire=1572496003&ei=Iw66Xa24H8PL3LUPiN25mAs&ip=2001%3A8003%3A749b%3Aa01%3A5cd8%3Ac610%3A6402%3Ad0fe&id=o-ADsVnoOoBQ6-SWzYZU7gHES06s7xQptJG6hn9WcakITY&itag=18&source=youtube&requiressl=yes&mm=31%2C29&mn=sn-uxanug5-cox6%2Csn-ntqe6n7r&ms=au%2Crdu&mv=m&mvi=6&pl=39&initcwndbps=1655000&mime=video%2Fmp4&gir=yes&clen=44248820&ratebypass=yes&dur=917.768&lmt=1572416976690256&mt=1572474311&fvip=4&fexp=23842630&c=WEB&txp=5531432&sparams=expire%2Cei%2Cip%2Cid%2Citag%2Csource%2Crequiressl%2Cmime%2Cgir%2Cclen%2Cratebypass%2Cdur%2Clmt&sig=ALgxI2wwRQIhANTZJlBHFWQWCnfK11yvLiPUV26c6NzvqIMKjDwmsByMAiBUSy0ZJMo4GdHSiRU4xBDDLxLtzwKZAqAKCiB-1aViDQ%3D%3D&lsparams=mm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpl%2Cinitcwndbps&lsig=AHylml4wRAIgacvP3zjEq-rVEZFrX7a_hC6TR-Zab7Ii-Fbaupjs_PcCIHdZht4l4ioYL3ERz7WNiSbnOnhm5iYxEECaQXPP2hUp",
"video_title": "Arnold Schwarzenegger on Son-in-law Chris Pratt, Pranking Sylvester Stallone & Terminator’s Return",
"fmt_id": "18",
"fmt_quality": "640x360"
}
]
But when I try and loop through each entry with fillInOptions(), my loop is never completed because the length is apparently zero. However, when I dump the array using console.log() it tells me the length is 2, and displays the above. I need to be able to add each option to my dropdown.
Thankyou!
UPDATE: Added full code, sorry!
It looks like your .forEach() is the root of the problem. The parameters of a forEach are currentValue, index like this: array.forEach(function(currentValue, index) {}); but it looks like you're using them in the opposite way
Try rewriting that iteration to this:
ytFill.forEach(function(v, i) {
console.log(i);
ytdlOptions.append(new Option(v.fmt_quality, v.fmt_id));
});
Notice the difference in the order of v and i in the parameters.
I have array of functions/objects which I want to store to database, like this example:
function classPerson(firstName, lastName, activeStatus) {
this.firstName = firstName;
this.lastName = lastName;
this.activeStatus = activeStatus;
this.identify = function () {
return this.firstName + " " + this.lastName;
}
} // element
var persons = [];
var personsFromDatabase = [];
// define persons
var personOne = new classPerson('Bruce', 'Lee', true);
var personTwo = new classPerson('Chuck', 'Norris', false);
var personThree = new classPerson('Steven', ' Seagal', true);
// add persons to array
persons.push(personOne);
persons.push(personTwo);
persons.push(personThree);
// show persons data
for (var i = 0; i < persons.length; i++) {
alert(persons[i].identify());
}
// store to database
var toDatabase = JSON.stringify(persons);
alert(toDatabase);
// retrieve from database
var personsFromDatabase = JSON.parse(toDatabase);
// show persons data parsed from database
for (var i = 0; i < personsFromDatabase.length; i++) {
alert(personsFromDatabase[i].identify());
}
I transform persons array to string with JSON.stringify command and successfully store it to database.
When I load same string from database and transform back with JSON.parse to JS function/object I get list of simple objects (and error
TypeError: personsFromDatabase[i].identify is not a function
) instead of classPerson function/object and in console I can see that difference, like on picture below:
How can I achieve to get array of functions/objects instead of simple JS objects?
Fiddler link with example
You cannot save function in JSON, because function does not exist in JSON
But you can use second argument of stringify function to replace the function with value.
Like
var json = JSON.stringify(obj, function(key, value) {
if (typeof value === 'function') {
return value.toString();
} else {
return value;
}
});
As mentioned above, JSON has no functions as data types. You can only serialize strings, numbers, objects, arrays, and booleans (and null):
I have altered your example to provide a method to serialize and deserialize - which can be be as a basic template:
function ClassPerson(firstName, lastName, activeStatus) {
this.firstName = firstName;
this.lastName = lastName;
this.activeStatus = activeStatus;
this.identify = function () {
return this.firstName + " " + this.lastName;
}
} // element
ClassPerson.prototype.toJson = function() {
var data = {};
for(var prop in this) {
if(this.hasOwnProperty(prop) && (typeof this[prop] !== 'function')) {
data[prop] = this[prop];
}
}
return JSON.stringify(data);
};
ClassPerson.fromJson = function(json) {
var data = JSON.parse(json); // Parsing the json string.
if(data) {
var firstName = data.hasOwnProperty('firstName') ? data.firstName : "";
var lastName = data.hasOwnProperty('lastName') ? data.lastName : "";
var activeStatus = data.hasOwnProperty('activeStatus') ? data.activeStatus : "";
return new ClassPerson(firstName, lastName, activeStatus);
}
return {};
};
function serializeClassPersons(personArray) {
var serialised = [];
for (var i = 0; i < personArray.length; i++) {
serialised.push(persons[i].toJson());
};
return JSON.stringify(serialised);
};
function deserializeClassPersons(personsJsonString) {
var jsonStringArray = JSON.parse(personsJsonString); // this is an array
var persons = [];
for (var i = 0; i < jsonStringArray.length; i++) {
persons.push(ClassPerson.fromJson(jsonStringArray[i]));
};
return persons;
};
// add persons to array
var persons = [
new ClassPerson('Bruce', 'Lee', true),
new ClassPerson('Chuck', 'Norris', false),
new ClassPerson('Steven', ' Seagal', true)
];
var personsFromDatabase = [];
// show persons data
console.log('Using ClassPerson.identify():');
for (var i = 0; i < persons.length; i++) {
console.log(persons[i].identify());
};
console.log('Using ClassPerson toJson() and fromJson()');
for (var i = 0; i < persons.length; i++) {
var jsonPerson = persons[i].toJson();
console.log("json", jsonPerson);
var personFromJson = ClassPerson.fromJson(jsonPerson);
console.log("identify: ", persons[i].identify());
};
console.log('Serialize Persons Array to Json String');
var personsJson = serializeClassPersons(persons);
console.log(personsJson);
console.log('DeSerialize Json Persons String to Array');
var personsFromDatabase = deserializeClassPersons(personsJson);
console.log(personsFromDatabase);
The Output of this is:
hi iam new to javascript, i am trying to return a count from the function my code is like below
my code
function moredbCount(contentMoreArray2, ArrHeading) {
var sampleArr = [];
for (var a = 0; a < contentMoreArray2.length; a++) {
if (ArrHeading !== 'More') {
var fullHeading = ArrHeading + '-' + contentMoreArray2[a].name;
} else {
fullHeading = contentMoreArray2[a].name;
}
sampleArr.push(fullHeading);
}
var sampleCount = sampleHeadingCount(sampleArr);
return sampleCount.then(function (resultantCount) {
return resultantCount; //Here iam getting some count like 10 and returning it to the function;
});
}
var contentCount;
var totalCount = moredbCount(contentMoreArray2, ArrHeading);
totalCount.then(function (resultantTotalCount) {
return contentCount = resultantTotalCount
});
// Here i want to use contentCount 10, But iam getting undefined
Thanks In advance
return contentCount = resultantTotalCount won't return the count, but rather the response of assignment. In contentCount = resultantTotalCount, you are basically assigning the value of resultantTotalCount to contentCount.
You should use
function moredbCount(contentMoreArray2, ArrHeading) {
var sampleArr = [];
for (var a = 0; a < contentMoreArray2.length; a++) {
if (ArrHeading !== 'More') {
var fullHeading = ArrHeading + '-' + contentMoreArray2[a].name;
} else {
fullHeading = contentMoreArray2[a].name;
}
sampleArr.push(fullHeading);
}
var sampleCount = sampleHeadingCount(sampleArr);
return sampleCount.then(function (resultantCount) {
return resultantCount; //Here iam getting some count like 10 and returning it to the function;
});
}
var contentCount;
var totalCount = moredbCount(contentMoreArray2, ArrHeading);
totalCount.then(function (resultantTotalCount) {
return resultantTotalCount
});
I have the following string returned from an API and I want to convert it to an object hierarchy using javascript.
The string received is:
"paymentInfoList.paymentInfo(0).receiver.amount":"12.00"
I want to convert it to a javascript object like:
{
paymentInfoList: {
PaymentInfo: [{
receiver: {
amount: 12.0
}
}]
}
}
I could write my own parser but wonder if there is some code already out there.
Update
Based on the answer from #JasonCust here is a parser to parse a full response from the PayPal Adaptive Payments Pay method:
https://github.com/danielflippance/paypal-ap-parser
I don't know of an existing parser that handles that format. Maybe something on Paypal's developer site? If you roll your own you could do so using a recursive function like the example below. I haven't tested it thoroughly but it's a POC that it's easy enough to do.
function setObjVal(obj, paths, val) {
var path;
var arrayInfo;
if (paths.length === 0) {
return val;
}
obj = obj || {};
path = paths.shift();
arrayInfo = path.match(arrayRegExp);
if (arrayInfo) {
path = arrayInfo[1];
if (!Array.isArray(obj[path])) {
obj[path] = [];
}
obj[path][arrayInfo[2]] = setObjVal(obj[path][arrayInfo[2]], paths, val);
}
else {
obj[path] = setObjVal(obj[path], paths, val);
}
return obj;
}
var arrayRegExp = /^(\w+)\((\d+)\)$/;
var input = '"paymentInfoList.paymentInfo(0).receiver.amount":"12.00"';
var pair = input.split(':').map(function (str) { return str.replace(/"/g, ''); });
var newObj = setObjVal({}, pair[0].split('.'), pair[1]);
function setObjVal(obj, paths, val) {
var path;
var arrayInfo;
if (paths.length === 0) {
return val;
}
obj = obj || {};
path = paths.shift();
arrayInfo = path.match(arrayRegExp);
if (arrayInfo) {
path = arrayInfo[1];
if (!Array.isArray(obj[path])) {
obj[path] = [];
}
obj[path][arrayInfo[2]] = setObjVal(obj[path][arrayInfo[2]], paths, val);
}
else {
obj[path] = setObjVal(obj[path], paths, val);
}
return obj;
}
document.write('<pre>' + JSON.stringify(newObj, null, 4) + '</pre>');
Alternatively if you want to use lodash you could use _.set():
var newObj = _.set({}, pair[0].replace(/\(/g, '[').replace(/\)/g, ']'), pair[1]);
var input = '"paymentInfoList.paymentInfo(0).receiver.amount":"12.00"';
var pair = input.split(':').map(function (str) { return str.replace(/"/g, ''); });
var newObj = _.set({}, pair[0].replace(/\(/g, '[').replace(/\)/g, ']'), pair[1]);
document.write('<pre>' + JSON.stringify(newObj, null, 4) + '</pre>');
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.0/lodash.min.js"></script>
Since I can't resist a little puzzle, here's a clean recursive solution that works for the input you've given (scroll down and view the snippet for a little playground):
function objectFromExpression(expression, value) {
if (!expression) {
return value;
}
var obj = {};
var matchKeyIdxRest = /^(\w+)(?:\((\d+)\))?(?:\.(.+))?$/;
var matches = expression.match(matchKeyIdxRest);
if (!matches) {
throw new Error('Oops! There\'s a problem with the expression at "' + expression + '"');
}
var key = matches[1];
var idx = matches[2];
var rest = matches[3];
var next = objectFromExpression(rest, value);
if (idx) {
var arr = [];
arr[ parseInt(idx) ] = next;
obj[key] = arr;
} else {
obj[key] = next;
}
return obj;
}
function keyValueExpressionToKeyValue(str) {
var matchKeyVal = /^"([^"]+)":"([^"]+)"$/;
var matches = str.match(matchKeyVal);
if (!matches) {
throw new Error('Oops! Couldn\'t extract key and value from input!');
}
return matches.slice(1);
}
var input = '"paymentInfoList.paymentInfo(0).receiver.amount":"12.00"';
var keyAndValue = keyValueExpressionToKeyValue(input);
var key = keyAndValue[0]; // => paymentInfoList.paymentInfo(0).receiver.amount
var value = keyAndValue[1]; // => 12.00
objectFromExpression(key, value);
// => { paymentInfoList:
// { paymentInfo:
// [ { receiver:
// { amount: "12.00" }
// }
// ]
// }
// }
function objectFromExpression(expression, value) {
if (!expression) {
return value;
}
var obj = {};
var matchKeyIdxRest = /^(\w+)(?:\((\d+)\))?(?:\.(.+))?$/;
var matches = expression.match(matchKeyIdxRest);
if (!matches) {
throw new Error('Oops! There\'s a problem with the expression at "' + expression + '"');
}
var key = matches[1];
var idx = matches[2];
var rest = matches[3];
var next = objectFromExpression(rest, value);
if (idx) {
var arr = [];
arr[ parseInt(idx) ] = next;
obj[key] = arr;
} else {
obj[key] = next;
}
return obj;
}
function keyValueExpressionToKeyValue(str) {
var matchKeyVal = /^"([^"]+)":"([^"]+)"$/;
var matches = str.match(matchKeyVal);
if (!matches) {
throw new Error('Oops! Couldn\'t extract key and value from input!');
}
return matches.slice(1);
}
var inputEl = document.getElementById('input');
function onKeyUp() {
var outputEl = document.getElementById('output');
var input = inputEl.value.trim();
try {
var keyAndValue = keyValueExpressionToKeyValue(input);
var key = keyAndValue[0];
var value = keyAndValue[1];
var output = objectFromExpression(key, value);
outputEl.value = JSON.stringify(output, null, 2);
} catch (ex) {
outputEl.value = ex.toString();
}
}
inputEl.addEventListener('keyup', onKeyUp);
inputEl.dispatchEvent(new Event('keyup'));
label, textarea, input { display: block; }
label { font-family: sans-serif; }
input, textarea { font-family: monospace; width: 100%; margin-bottom: 1em; }
textarea { height: 15em; }
<label for="input">Input (type to see changes)</label>
<input id="input" value='"paymentInfoList.paymentInfo(0).receiver.amount":"12.00"'/>
<label for="output">Output</label>
<textarea id="output">Click the "Parse!" button!</textarea>
I have this code and i can add or edit the object if exists, but the "for" finish before the function onsuccess is called, then the index "for" is bad.
How to pass the index onSuccess?
Help!!!
var active = dataBase.result;
var data = "";
var object = "";
var index = null;
var request;
$(".layers").promise().done(function () {
var elements = document.getElementsByClassName('layers');
for (var i = 0; typeof (elements[i]) != 'undefined'; i++) {
if (elements[i].getAttribute("src").split("/")[4] !== "alpha.png") {
data = active.transaction([elements[i].getAttribute("src").split("/")[3]], "readwrite");
object = data.objectStore(elements[i].getAttribute("src").split("/")[3]);
index = object.index("by_Name");
request = index.get(String(elements[i].getAttribute("src").split("/")[4] + "/" + elements[i].getAttribute("src").split("/")[6]));
request.onsuccess = function (e) {
var result = e.target.result;
if (result === undefined) {
var resultPut = object.put({
Name: String(elements[i].getAttribute("src").split("/")[4] + "/" + elements[i].getAttribute("src").split("/")[6]),
Count: 1,
Type: String(elements[i].getAttribute("src").split("/")[4])
});
resultPut.onerror = function (e) {
alert(resultPut.error.name + '\n\n' + resultPut.error.message);
};
} else {
result.Count++;
var requestUpdate = object.put(result);
requestUpdate.onerror = function (event) {
alert(requestUpdate.error.name + '\n\n' + requestUpdate.error.message);
};
}
}(event);
}
}
alert("Finish");
})
The thing is that, by the time the for has ended, the transactions with the object store are not. What you could try is to encapsulate the index like this:
for(var i = 0; i < elements.length; i++) {
(function(myElement) {
if (myElement.getAttribute("src").split("/")[4] !== "alpha.png") {
...
}
})(elements[i]);
}