AngularJS: how do i get data into an object and array? - javascript

i am trying to get data out of a spreadsheet into an array. I have already stored the data in javascript variables. But now i need those varriables to get stored as an obect in my array. here is my code:
this.json = function(){
jQuery.getJSON("http://cors.io/?u=https://spreadsheets.google.com/feeds/list/1l4XTKaLZihj5WDRuZJE5Y7RQ7Cr7SD_-tH0ctwhizWc/od6/public/values?alt=json").success(function(data) {
console.log(data.feed.entry);
//try
for (var i = 0; i < data.feed.entry.length; i++) {
var id = data.feed.entry[i].gsx$id.$t;
var name = data.feed.entry[i].gsx$name.$t;
var price = data.feed.entry[i].gsx$price.$t;
var notcompatiblewith = data.feed.entry[i].gsx$notcompatiblewith.$t;
this.parts[i] = {"id": id, "name": name, "price": price, "comp": notcompatiblewith, "canAdd": true, "added": false};
};
});
};
i call the function this.json in my html with ng-init="myctrl.json()" and it calls it perfectly. in my console on inspect element i get the error: 'Uncaught TypeError: Cannot set property '0' of undefined'
my array should look like this if it is initialised well:
{
id: 1,
name: 'vitamine A',
price: 3,
canAdd: true,
added: false,
comp: [2, 5]
},
{
id: 2,
name: 'vitamine B',
price: 5,
canAdd: true,
added: false,
comp: [1, 3]
},
{
id: 3,
name: 'vitamine C',
price: 2,
canAdd: true,
added: false,
comp: [2]
},
{
id: 4,
name: 'Opium',
price: 20.95,
canAdd: true,
added: false,
comp: []
},
{
id: 5,
name: 'steroids',
price: 12.5,
canAdd: true,
added: false,
comp: [1]
}
edit: the array parts in initialised under my controller like this
var parts = [];
and is declared in my controller as
this.parts = parts;

When you call this it refers to jQuery. Therefor parts does not exist.
Also, you're doing it wrong. You should use a service for it, and in the service there's a angular's $http for handling ajax requests.
In your way you're not using angular correctly.
Read here: https://docs.angularjs.org/guide/services

You need to initialize this.parts variable with empty Array object:
this.json = function(){
jQuery.getJSON("http://cors.io/?u=https://spreadsheets.google.com/feeds/list/1l4XTKaLZihj5WDRuZJE5Y7RQ7Cr7SD_-tH0ctwhizWc/od6/public/values?alt=json").success(function(data) {
console.log(data.feed.entry);
this.parts = []; // <-- this line was added
// skipped
});
};
Also you can use push method of Array instead of this.parts[i] = ...:
this.parts.push({"id": id, ... });

Have you tried :
this.parts[i].push({"id": id, "name": name, "price": price, "comp": notcompatiblewith, "canAdd": true, "added": false});
Because :
this.parts[i] = {"id": id, "name": name, "price": price, "comp": notcompatiblewith, "canAdd": true, "added": false};
This will end up assigning only one value to array.Everytime array will get upadated of latest value and deleting previous value.

Related

Tell me how to handle objects before sending axios

I'm using React.
Raise the child object to the parent.
I want to delete the unnecessary value and send it.
const before = {
address_check: true,
loan_check: true,
oneroom_disable: true,
info: {
age: 13,
name: gogo,
item: [1,2,3]
},
face: {
life: [1,2,3]
}
};
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
const after = {
address_check: true,
age: 13,
name: gogo,
item: [1,2,3]
};
How can I change the status from before to after?
You can create object from other object like below:-
const after = {
address_check: before.address_check,
age: before.info.age,
name: before.info.name,
item: before.info.item
}
You can do something like this:
// Original data
const before = {
address_check: true,
loan_check: true,
oneroom_disable: true,
info: {
age: 13,
name: gogo,
item: [1,2,3]
},
face: {
life: [1,2,3]
}
};
// Destructure required fields
const {address_check, info: {age, name, item}} = before;
// Put them together for your new object
const after = {
address_check, age, name, item
}

Filtering and Referencing Array to an Object Array in Javascript

I have 2 arrays:
Time Stamp Array:
var timeStamp = [["0:00","1:00"], ["2:00","3:00"]];
Time Label Reference:
var timeLabels = [
{ name: "0:00", present: true, label: ["0:00", "1:00"], alterName:"" },
{ name: "1:00", present: true, label: ["1:00", "2:00"], alterName:"" },
{ name: "2:00", present: true, label: ["2:00", "3:00"], alterName:"" }]
I wanted to use Lodash to filter through the TimeStamp array but the methods I want are exclusive to object arrays. I currently have a for loop and it is not very elegant.
Ultimately, I want to create a TimeLabels object array thats present field is set to True or False if the time is present in the first index of timeStamp.
Referencing the Time Stamp Array above, the result would be:
var timeResult = [
{ name: "0:00", present: true, label: ["0:00", "1:00"], alterName:"" },
{ name: "1:00", present: false, label: ["1:00", "2:00"], alterName:"" },
{ name: "2:00", present: true, label: ["2:00", "3:00"], alterName:"" }]
I'm more used to using lodash but I'm wondering if other methods would be better to construct the solution or if a for loop, which I'm currently using is ok.
Foreach elment inside timeLabels use indexOf to determine whether label is present or not in timestamp.To use indexOf you have to convert object into string using JSON.stringify().
var timeLabels = [
{ name: "0:00", present: true, label: ["0:00", "1:00"], alterName:"" },
{ name: "1:00", present: true, label: ["1:00", "2:00"], alterName:"" },
{ name: "2:00", present: true, label: ["2:00", "3:00"], alterName:"" }];
timeStamp = [["0:00","1:00"], ["2:00","3:00"]];
results = timeLabels.forEach(function(res){
label = JSON.stringify(res.label);//converts into string
ts = JSON.stringify(timeStamp);//converts into string
if(ts.indexOf(label)>=0){ //checks whether label is present or not
res.present = true;
}
else{
res.present = false;
}
});
console.log(timeLabels);
We can use map to iterate and return each of the transformed item. Notice that I used assign instead of manually assigning the present property, this is to avoid mutating the objects inside the timeLabels collection. Lastly, we use the combination of intersectionWith and isEmpty() to get the present value (Note that the resulting value is negated).
var timeResult = _.map(timeLabels, function(item) {
return _.assign({}, item, {
present: !_(timeStamp)
.intersectionWith([item.label], _.isEqual)
.isEmpty()
});
});
var timeStamp = [
["0:00", "1:00"],
["2:00", "3:00"]
];
var timeLabels = [{
name: "0:00",
present: true,
label: ["0:00", "1:00"],
alterName: ""
},
{
name: "1:00",
present: true,
label: ["1:00", "2:00"],
alterName: ""
},
{
name: "2:00",
present: true,
label: ["2:00", "3:00"],
alterName: ""
}
];
var timeResult = _.map(timeLabels, function(item) {
return _.assign({}, item, {
present: !_(timeStamp)
.intersectionWith([item.label], _.isEqual)
.isEmpty()
});
});
console.log(timeResult);
body > div { min-height: 100%; top: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>
var tmpTimeStamp = timeStamp.map(function(ts){ return ts[0]+"_"+ts[1] });
timeResult = timeResult.map(function(t){
t.present = tmpTimeStamp.indexOf(t.label[0]+"_"+t.label[1]) > -1;
return t;
});

How to push array to nested child object of only matching parent properties?

Below is my JSON structure:
$scope.dataList = [{
CompanyName: null,
Location: null,
Client: {
ClientId: 0,
ClientName: null,
Projects:{
Id: 0,
Name: null,
}
}
}];
I have this data in dataList scope variable :
[{
CompanyName: XXXX,
Location: California,
Client:{
ClientId: 1,
ClientName: John Cena,
Projects:{
Id: 1,
Name: Abc,
}
}
}]
Now in the above record I need to find by company name and location and add Client array to matched company.
Now based on button click event I am getting 1 or more another record from http call like below:
[{
CompanyName: XXXX,
Location: California,
Client:[{
ClientId: 2,
ClientName: Undertaker,
Projects:{
Id: 2,
Name: Pqr,
}
}]
}]
Now I want to append this new client data to my dataList object for company XXXX and for location California.
This is how I am trying but I am getting errors:
$http.get("Url")
.then(function(data) {
for (var i = 0; i < data.length; i++) // when there will be more than 1 records in response i get from http call
{
var result = $.grep($scope.dataList, function (e)
{
//find records from dataList by Company name and Location
return (e.CompanyName == data[i].CompanyName) && (e.Location == data[i].Location);
});
//Push client Id 2 record in dataList
result.Client.push(data[i]);// error:result.Client is undefined
console.log(result);
}
});
You could use a check and move the content of Client into an array, before pushing to result.Client
if (!Array.isArray(result.Client)) { // check if not an array
result.Client = [result.Client]; // create one with the actual content
}
result.Client.push(data[i]);

Wrap the function into another function

I have the code that sorts an array of objects by the object property using lodash. It’s pretty simple:
_.sortBy(data.cycles, "id");
However, I discovered that data.cycles[].id might be a string, so I have to convert each property to number before passing it to _.sortBy. Is there any elegant way of doing it? I think I should combine _.property and parseInt somehow, but I don’t know how.
data.cycles might look like this:
[
{
"id": "20",
"name": "John"
},
{
"id": "15",
"name": "Sarah"
},
{
"id": "158",
"name": "Bill"
},
{
"id": "-6",
"name": "Jack"
},
{
"id": "59",
"name": "Bob"
}
]
I would compose a sortBy() callback as follows:
var collection = [
{ id: '20', name: 'John' },
{ id: 15, name: 'Sarah' },
{ id: 158, name: 'Bill' },
{ id: '-6', name: 'Jack' },
{ id: 59, name: 'Bob' }
];
_.sortBy(collection, _.flow(_.property('id'), parseInt));
// →
// [
// { id: '-6', name: 'Jack' },
// { id: 15, name: 'Sarah' },
// { id: '20', name: 'John' },
// { id: 59, name: 'Bob' },
// { id: 158, name: 'Bill' }
// ]
The flow() function is useful when you want to compose a callback function out of many functions, it just forwards the output to the next function in line. The property() function returns a function that gets the specified property name from it's argument. This is the id, and that gets passed to parseInt().
We're essentially mapping and sorting at the same time. This has an efficiency advantage, in addition to being a one-liner: it doesn't have to iterate over the whole collection twice. This isn't a big deal with smaller collections, but with larger collections, the impact is noticeable.
You might want to run map first and modify id, then do a sort.
In vanilla JS, it would look something like:
function mapFn(item){
item.id = parseInt(item.id, 10);
return item;
}
var sortedCycles = data.cycles.map(mapFn).sort(sortFn);
In lodash, you could have:
var sortedCycles = _.sortBy(_.map(data.cycles, mapFn), 'id');
// or
var sortedCycles = _.chain(data.cycles).map(mapFn).sortBy('id').value()

console.log not showing expected object properties

I have the following code in javascript in my node.js application.
However certain objects are not stored in my variable appointment. Even if I set them, when I directly access them it works: console.log(appointment.test);
What have I done wrong in this code?
var appointment = {
subscribed: false,
enoughAssis: false,
studentSlotsOpen: false
};
console.log(appointment);
for (var key in appointmentsDB[i]) {
appointment[key] = appointmentsDB[i][key];
}
appointment.test= "res";
console.log(appointment.test);
console.log(appointment);
And here is the produced output:
{ subscribed: false,
enoughAssis: false,
studentSlotsOpen: false }
res
{ comment: 'fsadsf',
room: 'dqfa',
reqAssi: 3,
maxStud: 20,
timeSlot: 8,
week: 31,
year: 2013,
day: 3,
_id: 51f957e1200cb0803f000001,
students: [],
assis: [] }
The variable console.log(appointmentsDB[i]) looks as:
{ comment: 'fsadsf',
room: 'dqfa',
reqAssi: 3,
maxStud: 20,
timeSlot: 8,
week: 31,
year: 2013,
day: 3,
_id: 51f957e1200cb0803f000001,
students: [],
assis: [] }
The following command:
console.log(Object.getOwnPropertyNames(appointmentsDB[i]), Object.getOwnPropertyNames(Object.getPrototypeOf(appointmentsDB[i])));
Shows:
[ '_activePaths',
'_events',
'errors',
'_maxListeners',
'_selected',
'_saveError',
'_posts',
'save',
'_pres',
'_validationError',
'_strictMode',
'isNew',
'_doc',
'_shardval' ] [ 'assis',
'timeSlot',
'db',
'_schema',
'id',
'base',
'day',
'collection',
'reqAssi',
'constructor',
'comment',
'year',
'room',
'students',
'week',
'_id',
'maxStud' ]
However I would expect that my last output also provides the entries test, subscribed, enoughAssis and studentSlotsOpen. What is wrong in this code?
The solution I found was to manually copy the elements I wanted to.
You probably have a Document object instead of a plain object. Those have a custom toJSON method which only yields the properties of your schema and the _id, but nothing else. If you are copying that method with your for-in-loop onto the appointment object, it will get serialized differently as well when logged.
Try
for (var key in appointmentsDB[i].toObject()) {
appointment[key] = appointmentsDB[i][key];
}
appointment.test= "res";
console.log(appointment);

Categories

Resources