Angular 2 - Apply a function to one object in an array - javascript

I have an array of "any" type with multiple objects inside of it, as so:
//List of posts (array)
this.posts = [
//First Post (object)
{
userFirst: 'Teyah',
userLast: 'Tharpe',
postText: 'Good morning, everyone! Have a good day. :)',
//First Post's comments (array)
comments: [
//First Comment (object)
{
cFirstName: 'Jalen',
cLastName: 'Tharpe',
theirComment: 'Thank you'
},
//Second Comment (object)
{
cFirstName: 'Gerald',
cLastName: 'Matthews',
theirComment: 'Thank you! You do the same.'
}
]
},
//Second Post (object)
{
userFirst: 'Jordan',
userLast: 'Gibson',
postText: 'What is the move for today?',
comments: [
{
cFirstName: 'Joshua',
cLastName: 'Stewart',
theirComment: 'Party at my house!!!'
}
]
}
];
As you can see, I have an array of posts, which contains objects, and within the post objects, I have a list of comments. I am trying to apply a comment()function, to only one of the objects. Say, posts[0]. Can someone let me know if this is within scope for Angular 2? If so, please help.
If more code/information is needed, please let me know.
Thank you.

Yes, this is within the scope of Angular, as it is in the scope of javascript! The detailed answer to your question depends on exactly what you want to do with your comment() function. I will try to anticipate a couple of things you might like to do.
Add a new comment to a certain post's comment array
addComment(post, comment) {
post.comments.push(comment);
}
Find a post based on its index and add a comment
addCommentUsingIndex(postIndex, comment) {
this.posts[postIndex].comments.push(comment);
}
Extract the number of comments for a given post
countComments(postIndex) {
return this.posts[postIndex].comments.length;
}
get an array of the full names of each commenter of a certain post
transformComments(postIndex) {
return this.posts[postIndex].comments.map(comment => {
return comment.cFirstName + ' ' + comment.cLastName
});
}
Does that roughly cover your requirements?

Related

How can I access multiply nested sub objects in javascript?

I have a larger code which handles and sorts data. In it I want to work with objects to keep it easier and better structured. I have multiple categories and all of them have different nested subobjects, which I have trouble accessing writing/reading.
I searched on the web, w3schools but couldn't find my mistake, so sry for this entry level question!
I wrote a test function to better understand objects!
function test(){
var report, time, name, date, value;
report = 'Income Statement';
time = 'Annually';
name = 'Revenue';
date = '2017';
value = '10000000';
data = {}
data[report] = {}
data[report][time] = {}
data[report][time][name] = {}
data[report][time][name][date] = value;
console.log(data);
}
As to my understanding what this code does is:
-create an empty object data
-create an empty subobject report
-create an empty subsubobject time
-create an empty subsubsubobject name
-gives the subsubsubobject name a key/value pair date:value
(at least that was my intention to do)
First I tried to skip creating empty objects and directly fill data{} with:
data = {}
data[report][time][name][date] = value; but he seems to cannot set properties to this.
So I created like above coded first empty subobjects for all subcategories, is this really necessary or am I falling for a simple syntax mistake?
However he still doesn't log me the desired output which would be:
{ 'Income Statement': { Annually: { Revenue: {2017:10000000} } } }
and instead gives me:
{ 'Income Statement': { Annually: { Revenue: [Object] } } }
Simply put.. what am I doing wrong? :D
Thanks in advance for any kind of help!
Best regards
I don't think you are doing anything wrong. I pasted same code in JS console and it is giving proper result.
Screenshot of console with result of function
Different ways to initialize object
Static Data
let data = {
'Income Statement': {
'Annually': {
'Revenue': {
'2017': '10000000'
}
}
}
}
document.querySelector("#data-result").innerHTML = JSON.stringify(data)
<div id="data-result"></div>
Dynamic Data
var report, time, name, date, value;
report = 'Income Statement';
time = 'Annually';
name = 'Revenue';
date = '2017';
value = '10000000';
let data = {
[report]: {
[time]: {
[name]: {
[date]: value
}
}
}
}
document.querySelector("#object-result").innerHTML = JSON.stringify(data)
<div id="object-result"></div>
You can also consider different ways to store same data.
Example -
let data = [{
report: 'Income Statement'
time: 'Annually'
name: 'Revenue'
date: '2017'
value: '10000000'
}]
So now, if you want data by date in future you can get that by using filter
let data_2017 = data.filter(x => x.date === '2017');
It is correct !! I received { Income Statement: { Annually: { Revenue: {2017:10000000} } } } at console as an output with your given code.
Are u trying to save that data in some variable using test() ??
If yes then you need to use return data at the end of the definition on the function test instead of consol.log(data).

How to get an array from an array in Meteor.js

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();
},
});

Preventing duplicate objects from being added to array?

I am building a little shop for a client and storing the information as an array of objects. But I want to ensure that I am not creating "duplicate" objects. I have seen similar solutions, but perhaps it is my "newness" to coding preventing me from getting the gist of them to implement in my own code, so I'd like some advice specific to what I have done.
I have tried putting my code in an if look, and if no "part", my variable looking for part number, exists in the code, then add the part, and could not get it to function.
Here is the function I am working on:
function submitButton(something) {
window.scroll(0, 0);
cartData = ($(this).attr("data").split(','));
arrObj.push({
part: cartData[0],
description: cartData[1]
});
}
arrObj is defined as a global variable, and is what I am working with here, with a "part" and a "description", which is the data I am trying to save from elsewhere and output to my "#cart". I have that part working, I just want to ensure that the user cannot add the same item twice. (or more times.)
Sorry if my code is shoddy or I look ignorant; I am currently a student trying to figure these things out so most of JS and Jquery is completely new to me. Thank you.
You can create a proxy and use Map to hold and access values, something like this
let cart = new Map([{ id: 1, title: "Dog toy" }, { id: 2, title: "Best of Stackoverflow 2018" }].map(v=>[v.id,v]));
let handler = {
set: function(target,prop, value, reciver){
if(target.has(+prop)){
console.log('already available')
} else{
target.set(prop,value)
}
},
get: function(target,prop){
return target.get(prop)
}
}
let proxied = new Proxy(cart, handler)
proxied['1'] = {id:1,title:'Dog toy'}
proxied['3'] = {id:3,title:'Dog toy new value'}
console.log(proxied['3'])
Assuming the 'part' property is unique on every cartData, I did checking only based on it.
function submitButton(something) {
window.scroll(0, 0);
cartData = ($(this).attr("data").split(','));
if(!isDuplicate(cartData))
arrObj.push({
part: cartData[0],
description: cartData[1]
});
}
const isDuplicate = (arr) => {
for(obj of arrObj){
if(arr[0] === obj.part)
return true;
}
return false;
}
If you want to do the checking on both 'part' and 'description' properties, you may replace the if statement with if(arr[0] === obj.part && arr[1] === obj.description).
Thanks everyone for their suggestions. Using this and help from a friend, this is the solution that worked:
function submitButton(something) {
window.scroll(0,0);
cartData = ($(this).attr("data").split(','));
let cartObj = {
part: cartData[0],
description: cartData[1],
quantity: 1
}
match = false
arrObj.forEach(function(cartObject){
if (cartObject.part == cartData[0]) {
match = true;
}
})
console.log(arrObj);
if (!match) {
arrObj.push(cartObj);
}
Okay, you have multiple possible approaches to this. All of them need you to specify some kind of identifier on the items which the user can add. Usually, this is just an ID integer.
So, if you have that integer you can do the following check to make sure it's not in the array of objects:
let cart = [{ id: 1, title: "Dog toy" }, { id: 2, title: "Best of Stackoverflow 2018" }];
function isInCart(id) {
return cart.some(obj => obj.id === id);
}
console.log(isInCart(1));
console.log(isInCart(3));
Another approach is saving the items by their id in an object:
let cart = { 1: { title: "Dog toy" }, 2: { title: "Best of Stackoverflow 2018" } };
function isInCart(id) {
if(cart[id]) return true;
return false;
}
Try to use indexOf to check if the object exists, for example:
var beasts = ['ant', 'bison', 'camel', 'duck', 'bison'];
console.log(beasts.indexOf('aaa'));
// expected output: -1

auto increment a field in mongodb

I need to find a way to auto-increment the "Bill_id" field by 1 , whenever I insert a new item to a nested array in a collection:
this is the structure of the nested document
I also found this demo on the official documentation :
https://docs.mongodb.com/v3.0/tutorial/create-an-auto-incrementing-field/
function getNextSequence(name) {
var ret = db.counters.findAndModify(
{
query: { _id: name },
update: { $inc: { seq: 1 } },
new: true
}
);
return ret.seq;
}
but I didn't know how to use the solution because it's proposing a JavaScript function that does all the work
However I am working with python script , and to be specific a REST API using flask
Write a similar function mentioned in the docs, in python. This is what I use.
def getLastUserId(self):
if len(list(self.find())) is not 0:
last_user = list(self.find({}).sort("user_id", -1).limit(1))
return last_user[0]["user_id"]
else:
return 0
This will return the "user_id" of the last added document. Just increment it by one, and do a simple insert for the new document.

Parsing a JSON object in node.js

{"__v":0,"_id":{"$oid":"55f13d34258687e0bb9e4385"},"admin":true,"email":"emaple1#gmail.com","last_login":"11:25:24 AM","name_surname":"user1","password":"qwerty123"}
{"__v":0,"_id":{"$oid":"55ef49dd5d610eab18719deb"},"admin":true,"email":"emaple2#gmail.com","last_login":"12:25:24 AM","name_surname":"user2","password":"qwerty123"}
{"__v":0,"_id":{"$oid":"55f0173bb3322bf560724fd1"},"admin":true,"email":"emaple3#gmail.com","last_login":"10:25:24 AM","name_surname":"user3","password":"qwerty123"}
Hello, I working in nodeJS file and there I have a collection of JSON objects and I would like to make a search through it. For each user from this list I need to compare the field "last_login" .
I am new to nodeJS can someone help? Thank you!
This is what i have tried:
User.find({}, {last_login: }, function(err, docs) {
if (err) {
return res.json({ success: false, message: 'Failed to display last logins.' });
}
docs.forEach(function(doc, index) {
res.json({success: true, message: 'time of last login', last_login: doc.last_login});
})
//res.json(users);
});
});   
Where last_login is a field in the User object and basically I need to iterate over all users in the db and extract only the last_login and display in in the response.I don’t know what value to put in the find() inside the curly braces
this is the part where I am stuck
I’ve slightly changed the function and it returns a JSON object containing the info about one user that is matched with the search query. The problem is, the console displays the result, as a whole object, although I want to get only a specific key value pair and namely last_login: value
function searchByUserName(name_surname) {
    return list.filter(function(user) {
        return user.name_surname === name_surname;
    });
}
var a = searchByUserName('user1');
for (last_login in a ) {
  if (a.hasOwnProperty(last_login)) {
    console.log("last_login" + "=" + JSON.stringify(a[last_login]))
  }
}
Can you tell me please, what change to make in order to get only the last_login key
here is a sample result from the console.log() that I receive:
last_login={"__v":0,"_id":{"$oid":"55f13d34258687e0bb9e4385"},"admin":true,"email":"emaple1#gmail.com","last_login":"11:25:24 AM","name_surname":"user1","password":"qwerty123"}
although I want last_login = “last_login”: 11:25:24 AM
Assuming it's an array of objects like bellow.
var users = [{"__v":0,"_id":{"$oid":"55f13d34258687e0bb9e4385"},"admin":true,"email":"emaple1#gmail.com","last_login":"11:25:24 AM","name_surname":"user1","password":"qwerty123"},
{"__v":0,"_id":{"$oid":"55ef49dd5d610eab18719deb"},"admin":true,"email":"emaple2#gmail.com","last_login":"12:25:24 AM","name_surname":"user2","password":"qwerty123"},
{"__v":0,"_id":{"$oid":"55f0173bb3322bf560724fd1"},"admin":true,"email":"emaple3#gmail.com","last_login":"10:25:24 AM","name_surname":"user3","password":"qwerty123"}];
you can create a function like bellow
function searchByLastLogin(last_login) {
return users.filter(function(user) {
return user.last_login === last_login;
});
}
console.log(searchByLastLogin("12:25:24 AM"));
console.log(searchByLastLogin("10:25:24 AM"));
console.log(searchByLastLogin("11:25:24 AM"));
It will retrun a array of users whose last_login will match to given parameter last_login.
Update
What I understood from your comment bellow, you want last logins of every user.
For that you can do something like bellow
var last_logins = users.map(function(user){
return user.last_login;
});
console.log(last_logins); //prints [ '11:25:24 AM', '12:25:24 AM', '10:25:24 AM' ]
References
filter | map
I don’t know what value to put in the find() inside the curly braces this is the part where I am stuck
If I understand correctly, you only want to get the last_login field for the user model, and that's what you're struggling with ?
According to the documentation, this should work if you only want to get that field :
User.find({}, {last_login:1, _id:0})

Categories

Resources