Removing attribute when writing file to JSON - javascript

I have requested data from an API which is returned in JSON format, then written to a JSON file stored on a web server. I am then displaying filtered contents from the stored JSON file to a webpage using Angular.js.
The NodeJS code I am using to write the the API response to a file is the following:
var doNotStringify = {
currentTarget: true,
delegateTarget: true,
originalEvent: true,
target: true,
toElement: true,
view : true,
count : true,
message : true,
error : true,
}
tl.employees.all(function(response){
fs.writeFile(file, JSON.stringify(response, function(key, value) {
var result = value;
if(doNotStringify.hasOwnProperty(key)) {
result = undefined;
}
return result;
}, 4));
});
This strips out all unneeded elements, apart from 'Data'. I can't strip out Data in the function above as it deletes the contents of the element. So the result is the following JSON file:
{
"Data": [{
"FirstName": "Test1",
"LastName": "User",
}, {
"FirstName": "user",
"LastName": "user",
}, {
"FirstName": "Ropbert",
"LastName": "Jones",
}, {
"FirstName": "Jim",
"LastName": "Morrison",
}]
}
When editing out the 'Data' element manually, it works find in HTML/Angular with the following:
<td>{{player.firstName}}</td>
However, when a new JSON file is written containing the 'Data' element, it breaks and isn't displayed on the web page.
So my Question:
Is there a way to exclude the 'Data' element from writing to a file using fs.writeFile and JSON.stringify?
Or, is there something I can do in Angular get around it?

If you just want to strip out the data part, You can just create another element with the contents.In Angular also, I think you can do that with your model. Here is an example(not angular specific):
var playerdata = {
"Data": [{
"FirstName": "Test1",
"LastName": "User",
}, {
"FirstName": "user",
"LastName": "user",
}, {
"FirstName": "Ropbert",
"LastName": "Jones",
}, {
"FirstName": "Jim",
"LastName": "Morrison",
}]
};
playerdata = playerdata["Data"];
console.log(playerdata);
playerdata.forEach(function(player){
console.log(player.FirstName);
})

Related

How to parse and test response as key/value from an array

I've got the following json response:
{
"vin": "BAUV114MZ18091106",
"users": [
{
"role": "PRIMARY_USER",
"status": "ACTIVE",
"securityLevel": "HG_2_B",
"firstName": "Etienne",
"lastName": "Rumm",
"nickName": "BastieW",
"isInVehicle": false
},
{
"role": "SECONDARY_USER",
"status": "ACTIVE",
"securityLevel": "HG_2_B",
"firstName": "Test",
"lastName": "DEde",
"isInVehicle": false
}
]
}
I want to test the "isInVehicle" key and pass the test, if it's true and fail the test, if it's false.
I was trying to do so with following test code, but it didn't work, tests are always passed, no matter what response I got.
pm.test("User is in Vehicle", () => {
_.each(pm.response.json(), (arrItem) => {
if (arrItem.isInVehicle === 'true') {
throw new Error(`Array contains ${arrItem.isInVehicle}`)
}
})
});
Are there any ideas on how to solve my problem?
I think you are iterating through an object(root object of your response) instead of the user array. The revised version would be:
var users = pm.response.users;
_.each(users, (arrItem) => {
if (arrItem.isInVehicle) {
//Do something if isInVehicle is true
}
})
});
You can do these using array properties,
some - returns true if at least one match the condition
every - returns true if all items match the condition
const response = {
"vin": "BAUV114MZ18091106",
"users": [{
"role": "PRIMARY_USER",
"status": "ACTIVE",
"securityLevel": "HG_2_B",
"firstName": "Etienne",
"lastName": "Rumm",
"nickName": "BastieW",
"isInVehicle": false
},
{
"role": "SECONDARY_USER",
"status": "ACTIVE",
"securityLevel": "HG_2_B",
"firstName": "Test",
"lastName": "DEde",
"isInVehicle": false
}
]
};
pm.test("User is in Vehicle", () => {
// I'm assuming you are looking for atleast one match
const atleastOneMatch = response.users.some(user => user.isInVehicle);
// if you are looking for all should match, uncomment the following code
// const allShouldMatch = response.users.every(user => user.isInVehicle);
if(atleastOneMatch) {
// do your stuffs here
}
})

Why am I getting TypeError when adding a property to an Observable

I am trying to add a property on an Observable after subscribing and assigning the response in my Angular 4 app.
getCourses() {
return this.coursesService.getCourses().subscribe(
res => {
this.courses = res;
for (const course of this.courses) {
course.isChecked = false;
}
}
);
}
The code works and creates the property on the Observable but I get the error below as well.
ERROR TypeError: Cannot create property 'isChecked' on boolean 'false' at SafeSubscriber._next at SafeSubscriber.webpackJsonp.../../../../rxjs/Subscriber.js.SafeSubscriber.__tryOrUnsub
How can I correct the code so that I don't get errors?
Solved!!!
So I didn't realize that at the end of the array of objects that the api was returning was false.
[{ "PersonID": "129", "FirstName": "Ash", "MiddleName": "E.", "LastName": "Green", "MemberID": "129346", "MemberNumber": "105", "MemberStatus": 2, "AffiliatedAgencyID": "160" }, { "PersonID": "221334", "FirstName": "Abs", "MiddleName": null, "LastName": "Plast", "MemberID": "1953", "MemberNumber": "2047", "MemberStatus": 1, "AffiliatedAgencyID": "13" }, false]
Once I created an if statement to account for the false at the end, my problem was fixed. The other object I was getting doesn't have this anomaly. So it wasn't happening.
If res is an array, you should be able to go trough it without any problem. But make sure that res is an array.
getCourses() {
return this.coursesService.getCourses()
.subscribe(res => this.courses = res.map(course => course.isChecked = false));
}
So I didn't realize that at the end of the array of objects that the api was returning was false.
[{ "PersonID": "129", "FirstName": "Ash", "MiddleName": "E.", "LastName": "Green", "MemberID": "129346", "MemberNumber": "105", "MemberStatus": 2, "AffiliatedAgencyID": "160" }, { "PersonID": "221334", "FirstName": "Abs", "MiddleName": null, "LastName": "Plast", "MemberID": "1953", "MemberNumber": "2047", "MemberStatus": 1, "AffiliatedAgencyID": "13" }, false]
Once I created an if statement to account for the false at the end, my problem was fixed. The other object I was getting doesn't have this anomaly. So it wasn't happening.

Delete an object in Scope

This question might not even be related to angularjs and the solution could be plain old js or jquery. But that is what i what to find out.
I want to implement a delete functionality for a particular user and i am wondering if there is a easier way to do this in angularjs or should it be plain old JS?
i have a fairly complex object for eg (going up to 4 levels):
{
"Department": [
{
"Name": "Accounting",
"users": [
{
"id": "1",
"firstName": "John",
"lastName": "Doe",
"age": 23
},
{
"id": "2",
"firstName": "Mary",
"lastName": "Smith",
"age": 32
}
]
},
{
"Name": "Sales",
"users": [
{
"id": "3",
"firstName": "Sally",
"lastName": "Green",
"age": 27
},
{
"id": "4",
"firstName": "Jim",
"lastName": "Galley",
"age": 41
}
]
}
]
}
this is displayed in a ng-repeat where we should Department and username. If I want to delete a particular user i make an api call and on success of it, I want to delete that object. so i have a js method like this
function DeleteUser(user) {
$.each(ctrl.UserData, function(index, value) {
var filteredPeople = value.filter((item) => item.id !== user.id);
});
The question I have is, if i want to delete this object is there any easier way to delete from model since i have the object here or i have to do the classic jquery way of using like $.grep or filter to iterate through each object and match by id and then delete it?
Presumably, you're iterating over the departments (accounting, sales) in your template, and then over the users in that department.
So you could have, in your template:
<button ng-click="deleteUser(user, department)">...</button>
And the method could thus be as simple as
$scope.deleteUser = function(user, department) {
// delete user from backend, then
department.users.splice(departments.users.indexOf(user), 1);
}
If you really don't want to pass the department, then loop over the departments, and use the above if departments.users.indexOf(user) returns a value that is >= 0.

Extracting data from nested object with AWS ec2.describeInstances in node.js

I am relatively new to JavaScript.
I am trying to extract specific information from AWS about my EC2 instances using describeInstances. Specifically, I want to be able to provide a list of InstanceIds and extract from the resulting object the value of the Tags with Key: "Name". Here is the base code:
// Load the SDK for JavaScript
var AWS = require('aws-sdk');
// Load credentials and set region from JSON file
AWS.config.loadFromPath('./.aws/config.json');
// Create EC2 service object
var ec2 = new AWS.EC2({apiVersion: '2016-11-15'});
var params = {
DryRun: false,
InstanceIds: ['i-0be50217a4028a044', 'i-08b83c1c428e9a1d2']
};
ec2.describeInstances(params, function(err, data) {
if (err) {
console.log("Error", err.stack);
} else {
console.log("Success", JSON.stringify(data));
}
});
Upon running this code, a large, hairy, and nested object is returned. The JSON.stringify() version of this is shown here:
{
"Reservations": [{
"ReservationId": "r-04e32387e546387ba",
"OwnerId": "543800113692",
"Groups": [],
"Instances": [{
"InstanceId": "i-08b83c1c428e9a1d2",
"ImageId": "ami-8aa998ea",
"State": {
"Code": 16,
"Name": "running"
},
"PrivateDnsName": "ip-10-77-113-210.us-west-2.compute.internal",
"PublicDnsName": "ec2-35-165-200-222.us-west-2.compute.amazonaws.com",
"StateTransitionReason": "",
"KeyName": "Security1",
"AmiLaunchIndex": 0,
"ProductCodes": [],
"InstanceType": "t2.micro",
"LaunchTime": "2017-02-14T14:59:11.000Z",
"Placement": {
"AvailabilityZone": "us-west-2b",
"GroupName": "",
"Tenancy": "default"
},
"Monitoring": {
"State": "disabled"
},
"SubnetId": "subnet-228da755",
"VpcId": "vpc-af0f0dca",
"PrivateIpAddress": "10.77.113.210",
"PublicIpAddress": "35.165.200.222",
"Architecture": "x86_64",
"RootDeviceType": "ebs",
"RootDeviceName": "/dev/sda1",
"BlockDeviceMappings": [{
"DeviceName": "/dev/sda1",
"Ebs": {
"VolumeId": "vol-00e55d6bf114bfcaa0",
"Status": "attached",
"AttachTime": "2017-02-09T15:37:34.000Z",
"DeleteOnTermination": true
}
}],
"VirtualizationType": "hvm",
"ClientToken": "vOiiS1486654656072",
"Tags": [{
"Key": "Name",
"Value": "Fenris"
}],
"SecurityGroups": [{
"GroupName": "launch-wizard-2",
"GroupId": "sg-2312072c"
}],
"SourceDestCheck": true,
"Hypervisor": "xen",
"EbsOptimized": false
}]
}, {
"ReservationId": "r-0bbcb12e5c1162c23",
"OwnerId": "543800113692",
"Groups": [],
"Instances": [{
"InstanceId": "i-0be50217a40028a044",
"ImageId": "ami-8ba011ea",
"State": {
"Code": 80,
"Name": "stopped"
},
"PrivateDnsName": "ip-10-77-118-17.us-west-2.compute.internal",
"PublicDnsName": "",
"StateTransitionReason": "User initiated (2016-12-05 16:49:45 GMT)",
"KeyName": "Security3",
"AmiLaunchIndex": 0,
"ProductCodes": [],
"InstanceType": "t2.medium",
"LaunchTime": "2016-12-02T15:50:08.000Z",
"Placement": {
"AvailabilityZone": "us-west-2b",
"GroupName": "",
"Tenancy": "default"
},
"Monitoring": {
"State": "disabled"
},
"SubnetId": "subnet-228da700",
"VpcId": "vpc-af0f1ccb",
"PrivateIpAddress": "10.77.118.17",
"StateReason": {
"Code": "Client.UserInitiatedShutdown",
"Message": "Client.UserInitiatedShutdown: User initiated shutdown"
},
"Architecture": "x86_64",
"RootDeviceType": "ebs",
"RootDeviceName": "/dev/sda1",
"BlockDeviceMappings": [{
"DeviceName": "/dev/sda1",
"Ebs": {
"VolumeId": "vol-1c211ac8",
"Status": "attached",
"AttachTime": "2016-11-22T01:54:52.000Z",
"DeleteOnTermination": true
}
}],
"VirtualizationType": "hvm",
"ClientToken": "RQbhg1479762230132",
"Tags": [{
"Key": "Name",
"Value": "Heimdall"
}, {
"Key": "Type",
"Value": "Product Dev"
}],
"SecurityGroups": [{
"GroupName": "LinuxAPIdev",
"GroupId": "sg-5ea11777"
}],
"SourceDestCheck": true,
"Hypervisor": "xen",
"EbsOptimized": false
}]
}]
}
This is way more info than I need or want. I want to find a way to get only the values of Reservations.Instances.Tags.Value from the Reservations.Instances.Tags.Name key.
I thought that just writing it that way would work. But strangely, I can't seem to access the Reservations.Instances object at all:
// Load the SDK for JavaScript
var AWS = require('aws-sdk');
// Load credentials and set region from JSON file
AWS.config.loadFromPath('./.aws/config.json');
// Create EC2 service object
var ec2 = new AWS.EC2({apiVersion: '2016-11-15'});
var params = {
DryRun: false,
InstanceIds: ['i-0be5987a41191a044', 'i-08b83c3fc28e9a1d2']
};
// call EC2 to retrieve policy for selected bucket
ec2.describeInstances(params, function(err, data) {
if (err) {
console.log("Error", err.stack);
} else {
console.log("Success", JSON.stringify(data.Reservations.Instances));
}
});
This results in:
Success undefined
What am I doing wrong? How do I access the lower level of data within Instances? It is obviously there... it shows up in JSON.stringify(), but clearly I don't have the right protocol for extracting it.
(P.S. Because of AWS credentials, you won't be able to run my code without minor changes. You'll need to reference your own credentials, and InstanceIds from your own EC2 instances.)
Reservations, Instances and Tags All are arrays that''s why :
Reservations[0].Instances[0].Tags[0].Value
// value of 1ˢᵗ tag of 1ˢᵗ instance of 1ˢᵗ reservation
and Not
Reservations.Instances.Tags.Value
Within your describeInstances() method, you can simply use
// for InstanceId : "i-08b83c1c428e9a1d2"
data.Reservations[0].Instances[0].Tags[0].Value;
// and for InstanceId : "i-0be50217a40028a044"
data.Reservations[1].Instances[0].Tags[0].Value;
You can anyway create a function, if required, to return the tags value if the object structure is known.

How to do ng-repeat on $firebaseArray output with multiple levels?

I am using $firebaseArray for collecting the data from Firebase. Output is as follows:
[
{
"BankAccount": {
"AccountHolder": "Tom Antony",
"AccountNumber": "56767887"
},
"Info": {
"BillingAddress": {
"City": "XYZ",
"State": "ABC"
},
"FullName": "Tom Antony",
"PhoneNumber": "634762347"
},
"$id": "dGUZX5SWi7aP0SNYLYqEiMdCYAS2",
"$priority": null
},
{
"Campaigns": {
"Settings": {
"Active": true
}
}
},
"Info": {
"BillingAddress": {
"City": "ABC",
"State": "DFG"
},
"FullName": "Mario",
"PhoneNumber": "634762347"
},
"$id": "tBqGZ7g6VwNYOWoVy7C1FHKZKFS2",
"$priority": null
}
]
My js is as follows:
const rootRef = firebase.database().ref().child('Users');
$scope.users = $firebaseArray(rootRef);
Each Array element will have different type of objects, but each will have a similar object called Info, which contains a field for FullName I need to apply ng-repeat on this FullName. My implementation is as shown below:
<div ng-repeat="user in users.Info">
<p ng-bind="user.FullName"></p>
</div>
But its not working. What are the mistakes I made here?
You are trying to iterate on the wrong property. You have two objects (user) which each have an Info property that you want the FullName from. You do not have two Info objects. Therefore, you should be iterating over the users, not iterating over users.Info.
Try this instead:
<div ng-repeat="user in users">
<p ng-bind="user.Info.FullName"></p>
</div>
Also, your object you pasted here wasn't valid JSON, you had an extra }.
Full Working example: http://plnkr.co/edit/ryfjhO0c3egHfKnaL9SQ?p=preview

Categories