As stated in previous questions here and on Google, I've added a step function to alter the data and provide me with the specific columns I need.
Here was a comment that said to use Lodash _.pick() method: https://stackoverflow.com/a/59944480/4236332
However, when doing that I end up with a completely empty results output.
Code:
parseFile(){
Papa.parse( this.file, {
header: true,
skipEmptyLines: true,
step: (results, parser) => {
results.data = _.pick(results.data , [ 'column1', 'column2']);
return results;
},
complete: function( results ){
console.log(results.data)
this.content = results;
this.parsed = true;
}.bind(this)
});
}
Before vs. After:
First console log holds the colums in the JSON I need plus several I want to filter out, Second log is completely empty.
Tried removing it from the step function and doing it in the complete function but same output.
EDIT 1:
I have tried testing the _.pick function on results.data[0] and this does work, so something is preventing _.pick() of looping through all json records in the list results.data?
Managed to fix this issue by looping through it with a _.map() function. This way it goes through every object in the array with the ._pick() method.
results.data = _.map(results.data, obj => _.pick(obj, [ 'column1','column2']));
Related
I'm parsing an order feed to identify duplicate items bought and group them with a quantity for upload. However, when I try to map the resulting array, it's showing [object Object], which makes me think something's converting the return into an object rather than an array.
The function is as follows:
function compressedOrder (original) {
var compressed = [];
// make a copy of the input array
// first loop goes over every element
for (var i = 0; i < original.length; i++) {
var myCount = 1;
var a = new Object();
// loop over every element in the copy and see if it's the same
for (var w = i+1; w < original.length; w++) {
if (original[w] && original[i]) {
if (original[i].sku == original[w].sku) {
// increase amount of times duplicate is found
myCount++;
delete original[w];
}
}
}
if (original[i]) {
a.sku = original[i].sku;
a.price = original[i].price;
a.qtty = myCount;
compressed.push(a);
}
}
return compressed;
}
And the JS code calling that function is:
contents: compressedOrder(item.lineItems).map(indiv => ({
"id": indiv.sku,
"price": indiv.price,
"quantity": indiv.qtty
}))
The result is:
contents: [ [Object], [Object], [Object], [Object] ]
When I JSON.stringify() the output, I can see that it's pulling the correct info from the function, but I can't figure out how to get the calling function to pull it as an array that can then be mapped rather than as an object.
The correct output, which sits within a much larger feed that gets uploaded, should look like this:
contents:
[{"id":"sku1","price":17.50,"quantity":2},{"id":"sku2","price":27.30,"quantity":3}]
{It's probably something dead simple and obvious, but I've been breaking my head over this (much larger) programme till 4am this morning, so my head's probably not in the right place}
Turns out the code was correct all along, but I was running into a limitation of the console itself. I was able to verify this by simply working with the hard-coded values, and then querying the nested array separately.
Thanks anyway for your help and input everyone.
contents: compressedOrder(item.lineItems).map(indiv => ({
"id": indiv.sku,
"price": indiv.price,
"quantity": indiv.qtty
}))
In the code above the compressedOrder fucntion returns an array of objects where each object has sku, price and qtty attribute.
Further you are using a map on this array and returning an object again which has attributes id, price and quantity.
What do you expect from this.
Not sure what exactly solution you need but I've read your question and the comments, It looks like you need array of arrays as response.
So If I've understood your requirement correctly and you could use lodash then following piece of code might help you:
const _ = require('lodash');
const resp = [{key1:"value1"}, {key2:"value2"}].map(t => _.pairs(t));
console.log(resp);
P.S. It is assumed that compressedOrder response looks like array of objects.
everyone. I would like the students who enroll a subject are shown in a table when this subject is selected in a dropdown list. The ID of these students is stored in an array. The problem is that this ID array retrieved from the document looks kind of strange. seem like there is an array in an array.
Like this shown in the console:
shown in console
{enrollment: Array(2)}
enrollment: Array(2)
0: "b1602231"
1: "B1560124"
length: 2
__proto__: Array(0)
__proto__: Object
And it throwed an error: Exception in template helper: Error: $in needs an array
So how could I solve this? I would really appreciate it if someone can give me some idea.
Below is the event handler and helper.
Template.subject.events({
‘change #dropdown’: function(event, template) {
var selectedValue = $(event.target).val();
var array = subject.findOne( { subjectCode:selectedValue }, { fields:{ _id:0, enrollment:1 } } );
Session.set(‘studentEnrolled’,array);
}
});
Template.student.helpers({
student: function() {
var listOfStudent = Session.get( ‘studentEnrolled’ );
return student.find( { studentID: { $in:listOfStudent } } );
}
});
//HTML
<template name="student">
{{#each student}}
<tr>
<td>{{name}}</td>
</tr>
{{/each}}
</template>
Copying my answer from the forums:
First of all, you are taking the whole subject document (and after the first answer, wrapping that array into another array) here:
Session.set('studentEnrolled',[array]);
Which means when you search here:
return student.find({studentID:{$in:listOfStudent}});
You are passing an array with a document in it, instead of the enrollments array.
What you want to do is store the enrollments in the session:
Session.set('studentEnrolled', array.enrollments);
I'd also recommend renaming the variable array since it's not an array, and that probably contributed to your confusion
Find get one records from data. u can convert in array using [data]
var array = subject.findOne({subjectCode:selectedValue}, {fields:{_id:0, enrollment:1}});
Session.set(‘studentEnrolled’,[array]);
}
// For async update
More: https://blog.meteor.com/using-promises-and-async-await-in-meteor-8f6f4a04f998
Template.hello.onCreated(function helloOnCreated() {
this.list = new ReactiveVar([]);
Meteor.call('getHobbits', (error, result) => {
this.list.set(result);
});
});
Template.hello.helpers({
hobbits() {
return Template.instance().list.get();
},
});
I have the following array with data:
[
{"count":1,"title":"Ark: Survival","platform":"Playstation PS4"},
{"count":2,"title":"Lara Croft:", "platform":"Playstation PS4"},
{"count":1,"title":"Madden NFL", "platform":"Playstation PS4"}
]
All in my angular Cart scope:
var data = $scope.cart;
now i would like to add to each row the order number, so i use a push:
$scope.cart.push({"orderNumber": $scope.OrderNumber});
the problem is that is adds the order number but as a separate row and not inside each of the rows. so my desired output should look like this:
[
{"count":1,"title":"Ark: Survival","platform":"Playstation PS4","orderNumber":1 },
{"count":2,"title":"Lara Croft:", "platform":"Playstation PS4","orderNumber":1},
{"count":1,"title":"Madden NFL", "platform":"Playstation PS4","orderNumber":1}
]
how would i push to each row of the array? i tried several versions but can't seem to get it to work.
in order to achieve that you should iterate through each object and set order number separately
angular.forEach($scope.cart, function (value, key) {
value.orderNumber = $scope.OrderNumber;
});
You need to iterate over each item and add the orderNumber as a property for each item. So you can use forEach function of the angular for that.
angular.forEach($scope.cart, (item) => item.orderNumber = $scope.OrderNumber)
just got an answer that i implemented but the user has deleted the response, however it works perfect, this was the solution that i used:
$scope.cart.forEach(item => item.orderNumber = $scope.OrderNumber)
I have an array that I send from the backend, from which I create a new array of objects, for which I then use JSON.stringify to make it ready for the selectize, the array looks like this then:
[{"question":"Challenge question"},{"question":"Challenge question"},{"question":"Challenge question"}... and so on
I am trying to use that new array with selectize, but no option gets rendered:
This is the script:
var engagementsOptions = [];
icoop.engagements.map(function(item) {
engagementsOptions.push({
"question" : item
});
});
$('#engagement_question').selectize({
options: JSON.stringify(engagementsOptions),
create: true,
});
I think there is a problem with the string you are constructing for the options argument. I think it should be a comma-delimited string. Try something like this maybe (not tested with selectize, just based on the docs)?
//example data
var data_from_server = [{"question":"Challenge question 1"},{"question":"Challenge question 2"},{"question":"Challenge question 3"}];
var engagementsOptions = [];
data_from_server.map(function(item) { engagementsOptions.push(item["question"]); });
$('#engagement_question').selectize({
options: engagementsOptions.join(','),
create: true,
});
In parse I have a class named "TestScore". Each object has a key named "quizName".
I need to get an array of unique "quizName" values. I wrote the below which queries the "TestClass" and loops through the results looking for unique "quizName" values.
At first seemed to do the job. But then I realized that the maximum number of returned objects is 1000. Soon there will be more than 1000 objects stored which means that this method will not guarantee that I end up will all values.
function loadTests(){
//create an array to hold each unique test name as we find them
var uniqueEntries = [];
//query parse to return TestScore objects
var TestScore = Parse.Object.extend("TestScore");
var query = new Parse.Query(TestScore);
query.limit(1000) //added this after realizing that the default query limit is only 100
query.find({
success: function(testScore) {
$(testScore).each(function(index, score) {
//here I loop though all of the returned objects looking at the "quizName" for each
if($.inArray(score.get("quizName"), uniqueEntries) === -1) {
//if the quiz name is not already in the "uniqueEntries" array, I add it to the array
uniqueEntries.push(score.get("quizName"));
}
});
//do stuff with quiznames here...., add them as options in select boxes mostly
}
});
}
I looked at {Parse.Query} notContainedIn(key, values) which looks promising but cant figure out if I can add values to the array as I find them. It seems like I would have to have an array to start with (defeating the whole point.)
This part of the docs "{Parse.Query} Returns the query, so you can chain this call." makes me think I might be able to chain queries together to get what I need, but that doesn't seem very efficient.
How can I retrieve unique values for key "quizName" when my class has > 1000 objects?
I'm sure you're long past this by now, but only way I know of to do it is to use one query after another by using a .skip(#) value for each query. So get 1000, then query again with .skip(1000), concatenate the items from the first list and second, then query again with .skip(2000), etc...
Be aware that I think there's a limit on skip values of 10,000. Don't take my word on that, just pointing you to something that I think is right that you should confirm if you think it applies to your situation.
I eventually found a tutorial online that I was able to modify and came up with the below. This effectively sets the return limit to 10,000 instead of 1,000 and allows setting several different parameters for the query.
My changes could surely be written better, maybe as an options object or similar but it works for my needs.
You can see a working demo here
function getStuff(){
// here we will setup and call our helper functions with callbacks to handle the results
var scheme =['SOTest',true]; // return all objects with value `true` in the `SOTest` column
// var scheme =['descending','createdAt']; // return all objects with sort order applied
// var scheme =''; // or just return all objects
// see `findChunk()` below for more info
var Remark = Parse.Object.extend("Remark");
schemePromise(Remark, scheme).done(function (all) {
console.log('Found ' + all.length+' Remarks');
$.each( all, function(i, obj){
$('#test').append(obj.get('Remark') +'<br>');
});
})
.fail(function (error) {
console.log("error: " + JSON.stringify(error));
});
}
getStuff(); // call our function
// helper functions used to get around parse's 1000 query limit
// raises the limit to 10,000 by using promises
function findChunk(model, scheme, allData) {
// if `scheme` was an empty string, convert to an array
// this is the default and returns all objects in the called class
if(scheme==''){ ['scheme',''] };
// will return a promise
var limit = 1000;
var skip = allData.length;
var findPromise = $.Deferred();
var query = new Parse.Query(model);
// to get all objects from the queried Class then sort them by some column
// pass `scheme` as an array like [ sort method, column to sort ]
if (scheme[0]=='descending') query.descending(scheme[1]);
else if (scheme[0]=='ascending') query.ascending(scheme[1]);
// to limt results to objects that have a certain value in a specific column
// pass `scheme` as an array like [ column name, value ]
else query.equalTo(scheme[0], scheme[1]);
// more options can easily be built in here using `scheme`
query
.limit(limit)
.skip(skip)
.find()
.then(function (results) {
findPromise.resolve(allData.concat(results), !results.length);
}, function (results) {
findPromise.reject(error);
});
return findPromise.promise();
}
function schemePromise(model, scheme, allResults, allPromise) {
// find a scheme at a time
var promise = allPromise || $.Deferred();
findChunk(model, scheme, allResults || [])
.done(function (results, allOver) {
if (allOver) {
// we are done
promise.resolve(results);
} else {
// may be more
schemePromise(model, scheme, results, promise);
}
})
.fail(function (error) {
promise.reject(error);
});
return promise.promise();
}