Can an object method be used to create an object? - javascript

Based on the initial object Contact, I have to create a second object. Sometimes the Contact object will not have certain properties. I wanted to know if there was a way to print value of ConsentDt using a method within an object.
I know that I could simply code "ConsentDt": Contact.CommPhoneConsentDt and if that key is not available, ConsentDt will not be printed in the final output. However, sometimes determining if certain keys should be printed are a little bit more complicated, e.g. only include Email in the final object if EmailConsentDt == 'Y'. I also know that I could write functions outside of the object to make these determinations, but I wasn't sure if there was a way to keep the logic all in one object. Thanks in advance!
let Contact = {
"Name": "Kyle Gass",
"CommPhone": "+9-999-999-9999",
"Email": "tenacious#d.org",
"CommPhoneConsentCd": "Y",
"CommPhoneConsentDt": "2019/8/1",
"EmailConsentCd": "N"
}
let Communications = {
"PhoneInfo" : {
"PhoneTypeCd": "Cell",
"PhoneNumber": Contact.CommPhone,
"PhoneNumberValidInd": "N",
"ContactPreferenceType": "Primary",
"ConsentCd": Contact.CommPhoneConsentCd,
"ConsentDt": function(Contact) {
if (Contact.hasOwnProperty("CommPhoneConsentDt")) {
return Contact.CommPhoneConsentDt
} else {
return
}
}
}
}
console.log(Communications.PhoneInfo.ConsentDt);
//I want ConsentDt of 2019/8/1 to print out

You can use the get syntax on the object:
Communications = {
"PhoneInfo" : {
"PhoneTypeCd": "Cell",
"PhoneNumber": Contact.CommPhone,
"PhoneNumberValidInd": "N",
"ContactPreferenceType": "Primary",
"ConsentCd": Contact.CommPhoneConsentCd,
get "ConsentDt"() {
if (Contact.hasOwnProperty("CommPhoneConsentDt")) {
return Contact.CommPhoneConsentDt
} else {
return
}
}
}
}
console.log(Communications.PhoneInfo.ConsentDt);
ConsentDt of 2019/8/1 is printed out

Related

Accessing JSON value with unique named subarrays

I want to sort a JSON array based on time value in a subarray with the key names of the subarrays being named uniquely.
I'm searching for the method to access key, value update_time of every element in Products so I can use that value in a sorting script.
I have tried sorting the array but can not determine how to access the key, values of the subarrays
Expected behavior should be that every unique_keyname_# element is available for sorting and is sorted for further processing in JavaScript. Ultimately with the newest unique_keyname_# as the first element in a list, based on the update_time key.
var obj = {
"company": {
"department_1": {
"Products": {
"unique_keyname_1": {
"product_owner": "co-worker-1",
"update_time": "unix_timestamp_1"
},
"unique_keyname_5": {
"product_owner": "co-worker-4",
"update_time": "unix_timestamp_45"
},
"unique_keyname_8": {
"product_owner": "co-worker-2",
"update_time": "unix_timestamp_5"
}
}
},
"department_2": {
"Products": {
"unique_keyname_3": {
"product_owner": "co-worker-1",
"update_time": "unix_timestamp_21"
},
"unique_keyname_6": {
"product_owner": "co-worker-2",
"update_time": "unix_timestamp_7"
},
"unique_keyname_4": {
"product_owner": "co-worker-3",
"update_time": "unix_timestamp_75"
}
}
}
}
}
I solved the issue by writing an intermediate script in python which makes the API response a valid array. From there it was fairly easy to sort the data.
Thanks for the replies confirming the data itself was deliverd to me in an inappropriate format!
regards
In your example, there are no arrays.
Anyway, in Javascript you can access a node using . like:
obj.company.department_1.Products.unique_keyname_1
Or using [] which gives you more freedom to use costume fields
obj["company"]["department_1"]["Products"]["unique_keyname_1"]
// can also be more dynamic as:
obj["company"]["department_"+ department_counter]["Products"]["unique_keyname_" + keyname_counter]
Is there a possibility that you will change the structure of your JSON? to make it more manangeable ?
if so, i would recommend the folowing structure:
var products = [
{
department: 'SomeDepartment',
productName: 'Something',
productOwner: 'Someone',
update_time: 'Sometime'
}
]
Then you can sort the array easy using Array.sort()
for the sort topic use this : Sort array of objects by string property value

how can i return the values from one specific object?

I am running a JSON server to create a simple login system. The data from the server looks like this:
{
"users": [
{
"name": "user1",
"password": "pass1",
"email": "useer1#user.com",
"id": 2,
"details": {
"first_name": "user1_1",
"last_name": "user1_2",
"gender": "male",
"pic": "",
"about": "fnbewhbdwie"
}
},
{
"name": "user2",
"password": "pass2",
"email": "user2#user.com",
"details": {
"first_name": "user2_1",
"last_name": "user2_2",
"gender": "male",
"pic": "",
"about": "cjkdbvcwvebxcnoewbvcu"
},
"id": 4
}
]
}
I have created a function to check if the name and password match from the user input, and if the condition is true I want to run another function that will return only the details of the object that have the name and password from the user input.
I have tried the find() method but it returns the details for the first object only
async getAcc() {
const {data} = await Axios
.get(`${BASE_URL}users`)
data.forEach(({name, password}) => {
if(this.nameInput.value === name && this.passInput.value === password){
showAcc();
}
else {
return false
}
}
)
function showAcc() {
let result = data.find(a => a.details)
console.log(result)
}
}
Putting aside the obvious problem with the user/pwd on the response, as mentioned on comments, I believe that what is wrong here is this:
First, your data is an array of objects.
So, by definition, 'find' will return the first entry that the lamba function successfully satisfies. In this case, you are passing the array into the find and saying, give me the first details object you find. It is doing the right thing.
I believe that your problem is on the forEach. Since you added name and pwd as parameters , it is only picking those properties for each item on the array. Try and change it to something like
.forEach(item => {,
which will send into the lamba function the complete object. Then, inside the method you will need to modify and use
if(this.nameInput.value === item.name
Finally, inside your if statement, you'll be able to even simplify your showAcc by sending the "details" property straight into the method like:
showAcc(item.details);
and
function showAcc(details) {
console.log(details);
}
Would be better if you had a sample we could edit , but I think this should work.
Good luck
I'd use the lodash filter method instead of find method.
Something like: _.filter(data, { 'name': 'user2', 'password': 'pass2' });
It should get you all the objects that match your criteria passed in the argument object as shown above.
WebDever may have pointed you to a better solution. I'll just point out my observation, which directly explains why you fail to print all the answers.
I don't know anything about any of the technology used, but it seems that the problem has to be the return value (or lack thereof) of the code block inside the forEach. Just showing the result, it appears, should in and of itself have no side effect in terms of stopping the iteration. So the key thing that happens when you first find a match is that you don't return 'false'. Up to that point, you've always been returning 'false'.
So my guess is that when you find a match, you're returning the result of the last expression rather than 'false', and that return value causes the iteration to stop. So change the code within the foreach to:
if(this.nameInput.value === name && this.passInput.value === password){
showAcc();
}
return false

MongoDB using parameter for nested location

have a little newbe problem although I couldn't find a solution for similar problems, that worked for me.
Here is my collection:
{
"_id": ObjectId("5bc712851224ceec702d9bdf"),
"index": "123456",
"name": "Jan",
"surname": "Nowak",
"grades": {
"IABD": [
2,
3.5,
4
],
"NPAD": [
4,
4,
5
]
}
}
now I need to push additional grades to specific (function parameters) courses.
So I tried tackling it on a few levels and I'd love somebody to walk me through it according to this:
First I wanted to succeed not passing course as a parameter:
function add_grade(index="123456", course="IABD", grade=5.5)
{
db.students.update( {"index" : index }, { $push: { "grades" : { "IABD" : grade } } } );
}
well nothing happened (grade was not added to the list of grades)
I wanted to see some result, so I wanted to see if $set would work and it did!
function add_grade(index="123456", course="IABD", grade=5.5)
{
db.students.update( {"index" : index }, { $set: { "grades" : { "IABD" : grade } } } );
}
but it threw away my entire grades object (as expected). At least I know I'm on the right track.
Question 1: Why $push didn't work the way I expected
Question 2: how to use course parameter in set/push?
Just to clarify Q2, I'm not lazy, I've tried many approaches, none of which worked, please help!
You can try below query. That push 6 into IABD
db.getCollection('students').update( { "index": "123456" }, { $push: { "grades.IABD" : 6 } });
$push is not working the way you are expecting because the array field is in an embedded document and to push you need to use
dot notation i.e. instead of
{ "$push": { "grades" : { "IABD" : grade } } }
what you need is to specify the field as dot notation
{ "$push": { "grades.IABD" : grade } }
To use the course parameter in push you would want to create an update object that holds the dot notation
{ "grades.<course>" : grade }
for example
var course = "IABD";
var grade = 5.5;
var update = {};
update["grades." + course] = grade;
printjson(update) // prints { "grades.IABD" : 5.5 }
So your function will look like
function add_grade(index="123456", course="IABD", grade=5.5) {
var update = {};
update["grades." + course] = grade;
db.students.update(
{ "index" : index },
{ "$push": update }
);
}

Getting values of json array in Mocha JS

I have following issue, this json is returned by api:
"products": {
"10432471": {
"id": 10432471
},
"10432481": {
"id": 10432481
}
}
and I need to get names of all variables under products array, how to get them?
That values are constantly changing everyday, so I can not refer to their names
Trying console.log(res.body.menu.categories[i].products.values()); but its not worked.
Any sugesstion how can I get 10432471 and 10432481 from products? Without referring to variable names.
You are able to get that via Object.keys(res.body.menu.categories[i].products)
To get the object properties, the shortest is using Object.keys()
var obj = {"products": {
"10432471": {
"id": 10432471
},
"10432481": {
"id": 10432481
}
}}
var properties = Object.keys(obj.products)
console.log(properties)

MongoDB updated object with item remove not saving

I'm using Angular Fullstack for an web app.
I'm posting my data by $http.post() my object:
{ title: "Some title", tags: ["tag1", "tag2", "tag3"] }
When I edit my object and try to $http.put() for example:
{ title: "Some title", tags: ["tag1"] }
In console I get HTTP PUT 200 but when I refresh the page I still recive the object with all 3 tags.
This is how I save in the MongoDB:
exports.update = function(req, res) {
if (req.body._id) {
delete req.body._id;
}
Question.findByIdAsync(req.params.id)
.then(handleEntityNotFound(res))
.then(saveUpdates(req.body))
.then(responseWithResult(res))
.catch(handleError(res));
};
function saveUpdates(updates) {
return function(entity) {
var data = _.merge(entity.toJSON(), updates);
var updated = _.extend(entity, data);
return updated.saveAsync()
.spread(function(updated) {
return updated;
});
};
}
Can someone explain how to save the object with removed items?
What I'm doing wrong?
This is pretty bad practice to use things like _.merge or _.extend in client ( meaning your nodejs client to database and not browser ) code after retrieving from the database. Also notably _.merge is the problem here as it is not going to "take away" things, but rather "augment" what is already there with the information you have provided. Not what you want here, but there is also a better way.
You should simply using "atomic operators" like $set to do this instead:
Question.findByIdAndUpdateAsync(
req.params.id,
{ "$set": { "tags": req.body.tags } },
{ "new": true }
)
.then(function(result) {
// deal with returned result
});
You also really should be targeting your endpoints and not having a "generic" object write. So the obove would be specically targeted at "PUT" for related "tags" only and not touch other fields in the object.
If you really must throw a whole object at it and expect an update from all the content, then use a helper to fix the update statement correctly:
function dotNotate(obj,target,prefix) {
target = target || {},
prefix = prefix || "";
Object.keys(obj).forEach(function(key) {
if ( typeof(obj[key]) === "object" ) {
dotNotate(obj[key],target,prefix + key + ".");
} else {
return target[prefix + key] = obj[key];
}
});
return target;
}
var update = { "$set": dotNotate(req.body) };
Question.findByIdAndUpdateAsync(
req.params.id,
update,
{ "new": true }
)
.then(function(result) {
// deal with returned result
});
Which will correctly structure not matter what the object you throw at it.
Though in this case then probably just directly is good enough:
Question.findByIdAndUpdateAsync(
req.params.id,
{ "$set": req.body },
{ "new": true }
)
.then(function(result) {
// deal with returned result
});
There are other approaches with atomic operators that you could also fit into your logic for handling. But it is best considered that you do these per element, being at least root document properties and things like arrays treated separately as a child.
All the atomic operations interact with the document "in the database" and "as is at modification". Pulling data from the database, modifiying it, then saving back offers no such guarnatees that the data has not already been changed and that you just may be overwriting other changes already comitted.
I truth your "browser client" should have been aware that the "tags" array had the other two entries and then your "modify request" should simply be to $pull the entries to be removed from the array, like so:
Question.findByIdAndUpdateAsync(
req.params.id,
{ "$pull": { "tags": { "$in": ["tag2", "tag3"] } } },
{ "new": true }
)
.then(function(result) {
// deal with returned result
});
And then, "regardless" of the current state of the document on the server when modified, those changes would be the only ones made. So if something else modified at added "tag4", and the client had yet to get the noficiation of such a change before the modification was sent, then the return response would include that as well and everything would be in sync.
Learn the update modifiers of MongoDB, as they will serve you well.

Categories

Resources