Using the following array with two objects that include another object inside I would like to know if there is a way to find which is the applicationID has applicantID equal with "5bd3480af09ddf0258c3a31d"
Array [
Object {
"__typename": "JobApplication",
"_id": "5be097753397465946e051fd",
"applicant": Object {
"__typename": "User",
"_id": "5bd83b9a62a9f33cf0f1033b",
},
},
Object {
"__typename": "JobApplication",
"_id": "5bdc7c8b3241cb5bc10ac694",
"applicant": Object {
"__typename": "User",
"_id": "5bd3480af09ddf0258c3a31d",
},
},
]
So in this case it has to return "5bdc7c8b3241cb5bc10ac694".
This are my two constants first will return the user id and second will return only the applications id.
const { _id } = this.props.getMe.me._id;
const applicationID = getJobApplicationsForThisJob.map(application => application._id);
I could check if the user id is in any of the objects like this
const applicantId = getJobApplicationsForThisJob.map(user => user.applicant._id);
const hasApplied = applicantId.includes(_id);
Thanks
You can use the .find method.
var item = arr.find(function(x) {
return x.applicant._id == find;
});
The find method returns the first found item or undefined if a record was not found.
var arr = [{
"__typename": "JobApplication",
"_id": "5be097753397465946e051fd",
"applicant": {
"__typename": "User",
"_id": "5bd83b9a62a9f33cf0f1033b",
}
}, {
"__typename": "JobApplication",
"_id": "5bdc7c8b3241cb5bc10ac694",
"applicant": {
"__typename": "User",
"_id": "5bd3480af09ddf0258c3a31d",
},
}];
var find = "5bd3480af09ddf0258c3a31d";
var item = arr.find(function(x) {
return x.applicant._id == find;
});
console.log(item != undefined ? item._id : "Not Found");
Since you are using Javascript, you would want to do something like my comment,
let _id = "5bd3480af09ddf0258c3a31d";
let list = []; //your list of objects.
let applicationResults = list.where( (app) => app.applicant._id = _id);
if (applicationResults.length == 0){
console.log("no applicantion with this applicant found.");
}else {
console.log("Found " + applicationResults.length + " Applications from this Applicant")
return applicationResults;
}
Related
I have the following json schema.
const myJson = {
"type": "typeName"
"firstName": "Steven",
"lastName": "Smith",
"address": {
"primary": {
"city": "abc",
"street": {
"name": {
"subName": "someName"
}
}
}
}
}
And I want to loop over each of the properties for required validation on this json, I have the following code so far which works if the property in the json is not nested.
let errors = [];
const typeName = ['firstName', 'lastName'],
const typeAttr = Object.keys(myJson);
typeName.forEach(attr => {
if (!typeAttr.includes(attr)) {
errors.push(`Missing field: ${attr}`);
}
});
How can I add the nested json property like primary, city, street and validate the way I have done it.
Here's how you can check nested properties on json object
const myJson = {
type: "typeName",
firstName: "Steven",
lastName: "Smith",
address: {
primary: {
city: "abc",
street: {
name: {
subName: "someName",
},
},
},
},
};
let errors = [];
const typeName = ["firstName", "lastName", "address.primary", "address.primary.city"];
function checkNested(obj, level, ...rest) {
if (obj === undefined) return false;
if (rest.length == 0 && obj.hasOwnProperty(level)) return true;
return checkNested(obj[level], ...rest);
}
typeName.forEach((attr) => {
let props = attr.split(".");
if (!checkNested(myJson, ...props)) {
errors.push(`Missing field: ${attr}`);
}
});
console.log(errors);
For reference on how to check Nested properties you can check this answer.
Test for existence of nested JavaScript object key
I would do something like this. This method gives whether the data is having all the provided keys or not i.e., will return either true or false
let obj = {"type":"typeName","firstName":"Steven","lastName":"Smith","address":{"primary":{"city":"abc","street":{"name":{"subName":"someName"}}}}};
const typeName = ['firstName', 'lastName', 'address', 'address.primary', 'address.primary.city', 'address.primary.street'];
const validate = (data, types) => {
return types.every(type => {
// Split the keys using `.`
const keys = type.split('.');
// Check if the length is more than 1,
// if yes, then we need to check deeply
if (keys.length > 1) {
let datum = {
...data
};
// Check through all the keys found using split
for (let key of keys) {
// if any key is not found or falsy then return false
if (!datum[key]) {
return false;
}
datum = datum[key];
}
return true;
} else {
// if the length of the keys is not more than 1 then it means
// the key is at the top level and return the value as boolean
return !!data[type]
}
})
}
console.log(validate(obj, typeName));
console.log(validate(obj, ['firstName', 'lastName', 'address', 'address.primary', 'address.primary.zip']));
This below method will return the keys that were not present in the provided data
const validate = (data, types) => {
let errors = [];
types.forEach(type => {
const keys = type.split('.');
let datum = {
...data
};
// Loop through the keys
for (let [index, key] of keys.entries()) {
// Check if the key is not available in the data
// then push the corresponding key to the errors array
// and break the loop
if (!datum[key]) {
errors.push(keys.slice(0, index + 1).join('.'));
break;
}
datum = datum[key];
}
})
return errors;
}
const obj = {"type":"typeName","firstName":"Steven","lastName":"Smith","address":{"primary":{"city":"abc","street":{"name":{"subName":"someName"}}}}};
const typeName = ['firstName', 'lastName', 'address', 'address.primary', 'address.primary.city', 'address.primary.street'];
console.log(validate(obj, ['firstName', 'lastName']));
console.log(validate(obj, ['firstName', 'lastName', 'address', 'address.primary', 'address.primary.zip']));
console.log(validate(obj, [...typeName, 'test', 'address.primary.zip', 'address.test.zip']));
Use JSON Schema, a proposed IETF standard with tons of library implementations available for several languages for describing, generating, and validating JSON documents.
To require your JSON to have all the properties be present, you'll need a JSON Schema like below.
let typeNameSchema = {
"$schema": "http://json-schema.org/draft-07/schema",
"$id": "https://example.com/typename.schema.json",
"title": "Type Name",
"description": "A person's name and address details",
"type": "object",
"required": [
"firstName",
"lastName",
"address"
],
"properties": {
"type": {
"type": "string"
},
"firstName": {
"type": "string"
},
"lastName": {
"type": "string"
},
"address": {
"type": "object",
"required": [
"primary"
],
"properties": {
"primary": {
"type": "object",
"required": [
"city",
"street"
],
"properties": {
"city": {
"type": "string"
},
"street": {
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"type": "object",
"required": [
"subName"
],
"properties": {
"subName": {
"type": "string"
}
}
}
}
}
}
}
}
}
}
}
Then use any library to validate your JSON data against the above schema. jsonschema is one of the most popular JSON Schema validators for JavaScript. Here's how to validate your myJson data against the above typeNameSchema.
const Validator = require('jsonschema').Validator;
const validator = new Validator();
console.log(validator.validate(myJson, typeNameSchema)); // result
Validation results will be returned in a ValidatorResult object with the most important properties valid of type boolean and errors of type ValidationError[]. ValidationError object will have the property name and error message.
This is Browser localstorage Object referred as dataset
let dataset = localStorage.getItem('dataset') !== null ? leech : [];
[
{
"id": 123,
"name": "abc"
},
{
"id": 456,
"name": "bcd"
}
]
This is the initial data object available I want to add more field to a particular id.
This is what I want :
[
{
"id": 123,
"name": "abc"
},
{
"id": 456,
"name": "bcd",
"status":1
}
]
This my code to find the particular id
const user = dataset.find(user => user.id == 456);
Now how can I add status to user and update the user in the dataset?
You've already found the user by using Array.prototype.find() so all you need to do then is add the status property
// const dataset = JSON.parse(localStorage.getItem("dataset"))
const dataset = [{"id":123,"name":"abc"},{"id":456,"name":"bcd"}]
const user = dataset.find(({ id }) => id === 456)
if (user) {
user.status = 1
}
console.info(dataset)
.as-console-wrapper { max-height: 100% !important }
If you then want to store the modified data back into localStorage, use localStorage.setItem() and JSON.stringify()
localStorage.setItem("dataset", JSON.stringify(dataset))
If you want keep dataset initial value, and would like to get a new array, you can use Array.reduce() method.
const dataset = [
{
"id": 123,
"name": "abc"
},
{
"id": 456,
"name": "bcd"
}
]
const output = dataset.reduce((acc, cur) => {
if (cur.id === 456) cur.status = 1;
acc.push(cur);
return acc;
}, []);
console.log(output);
If you want to update dataset, you can use Array.forEach() method.
const dataset = [
{
"id": 123,
"name": "abc"
},
{
"id": 456,
"name": "bcd"
}
]
dataset.forEach(user => {
if (user.id === 456) user.status = 1;
});
console.log(dataset);
You could do with Array#Findindex with callback return function. so could pass the originaldata,searchId and update object. In this method you could updated object easily
Why i suggest findIndex
Because findindex not running entire loop or iteration. If the match
detect on first iteration they will break the loop and returning the
result.For long iteration its more faster than other loop (reduce,forEach)
const data = [ { "id": 123, "name": "abc" }, { "id": 456, "name": "bcd" } ]
function update(dataset,searchId,addtionObject){
let ind = dataset.findIndex(({id}) => id == searchId);
dataset[ind] = {...dataset[ind],...addtionObject}; //join the new and old array
return dataset
}
console.log(update(data,456,{status:1}))
If you want to create new state objet, you can use immer for that.
Immer will produce the nextState based on the mutations to the draft state.
import produce from "immer";
const baseState = [
{
id: 123,
name: "abc",
},
{
id: 456,
name: "bcd",
},
];
const nextState = produce(baseState, (draftState) => {
draftState[1].status = 1;
});
I have an object like the following :
[
{
"uid": "aaa-aaa",
"name": "foo",
"children": []
},
{
"uid": "aaa-bbb",
"name": "bar",
"children": [
{
"uid": "aaa-bbc",
"name": "baz",
"children": []
},
{
"uid": "aaa-ccc",
"name": "fooz",
"children": [
{
"uid": "aaa-bcb",
"name": "Yeah !",
"children": []
}
]
}
]
}
]
I am trying to write a function that would take that object an uid as parameters and would return a path to the element with the uid in that object (or null if it's not found).
Something like this :
> getElementPath(bigObject, 'aaa-bcb')
[1, "children", 1, "children", 0]
or
> getElementPath(bigObject, 'aaa-bcb')
[1, 1, 0]
I know the function has to be recursive since there should be no limit in nesting levels. I have tried this but it always returns null :
function getElementPath (haystack, uid, currentPath = []) {
if (haystack.uid === uid) {
return currentPath
}
if (Array.isArray(haystack.children)) {
for (let i = 0; i < haystack.children.length; i++) {
let newPath = [...currentPath, i]
let path = getElementPath(haystack.children[i], uid, newPath)
if (path !== null) {
return path
}
}
}
return null
}
I'd use flat
Flatten the object and then loop over the Object keys until you find the one that has the appropriate value. Once you find it, the key is the path.
https://www.npmjs.com/package/flat
My (naive and quick) implementation would look like this. But what I don't love about it is that it knows to look at the "children" property, it's fine if you're data structure is well defined and doesn't change very often, the flat idea will work no matter if you change your data structure or not.
getPathForUid = (uid,obj,thisPath = []) => {
if(Array.isArray(obj)) {
return obj.reduce((acc,item,idx) => getPathForUid(uid,item,thisPath.concat(idx)),[]);
}
return obj.uid === uid ? thisPath : getPathForUid(uid,obj.children,thisPath.concat('children'));
}
Try this:
function getObject(listaJson, uid) {
var object = null,
param,
type = null;
if (listaJson.uid === uid) {
return listaJson;
}
for (param in listaJson) {
type = typeof(listaJson[param]);
if (type.toString().toLowerCase() === 'object') {
object = getObject(listaJson[param], uid);
}
if (object) {
return object;
}
}
return object;
}
console.log(getObject(json, 'aaa-aaa'));
console.log(getObject(json, 'aaa-bbb'));
console.log(getObject(json, 'aaa-bbc'));
console.log(getObject(json, 'aaa-ccc'));
console.log(getObject(json, 'aaa-bcb'));
console.log(getObject(json, 'aaa-xxx')); // null
console.log(getObject(json, 'yyy-jjj')); // null
I have this JSON Response from API call
[
{
"id": 20599,
"name": "Deliver",
"options": [
{
"id": 63775,
"name": "Item",
"dataType": "SelectMultiOption",
"required": false,
"options": [
{
"id": 426,
"name": "Towels"
},
{
"id": 427,
"name": "Toothbrush"
},
{
"id": 428,
"name": "Pillow"
}
]
}
]
}
]
I am using this code to get the id of the service "Deliver"
var data = JSON.parse(responseBody);
var loop_count = 0
for (count = 0; count < data.length; count++)
{
if (data[count].name == "Deliver")
{
var job_id = data[count].id;
postman.setEnvironmentVariable("service_id", job_id);
}
}
The questions are:
How can I get value from array "options", I need to get the "id":
63775 and store as "item_id" and the "name":"Item" as "item_name" postman variables.
Then I need to select the "options" nested in record
"Item" and select the option "name": "Toothbrush" and store in postman
variable "svc_optn_optn_name" and it's "id" stored in
"svc_optn_optn_id"
Here I am giving my own suggestion for your problem with few lines of code. I am not sure, how are you going to use these values. I also don't know if the outer options array will always have 1 item or more. I have just tried to satisfy your questions.
Please ask/comment, if you have more doubts or I am wrong.
I have created a function getAllPostmanDataFrom(obj) which takes object as parameter which is the value of data[count], gathers necessary info in other object postmanObj and returns it to the caller.
function getAllPostmanDataFrom(obj) {
const item_id = obj.options[0].id;
const item_name = obj.options[0].name;
const svc_optn_optn_name = obj.options[0].options[1].name;
const svc_optn_optn_id = obj.options[0].options[1].id;
const postmanObj = {item_id, item_name, svc_optn_optn_id, svc_optn_optn_name}; // Return object
return postmanObj;
}
var data = [
{
"id": 20599,
"name": "Deliver",
"options": [
{
"id": 63775,
"name": "Item",
"dataType": "SelectMultiOption",
"required": false,
"options": [
{
"id": 426,
"name": "Towels"
},
{
"id": 427,
"name": "Toothbrush"
},
{
"id": 428,
"name": "Pillow"
}
]
}
]
}
]
var count = 0;
var obj = data[count];
var postmanObj = getAllPostmanDataFrom(obj);
//var {item_id, item_name, svc_optn_optn_id} = postmanObj;
console. log(postmanObj)
/*
console.log(item_id);
console.log(item_name);
console.log(svc_optn_optn_id);
console.log(svc_optn_optn_name);
*/
Finally, you can use values contained in postmanObj as follows:.
postman.setEnvironmentVariable("item_id", postmanObj.item_id);
postman.setEnvironmentVariable("item_name", postmanObj.item_name);
And so on.
This is the solution
var data = JSON.parse(responseBody);
variable named as data
var loop_count = 0
for (count = 0; count < data.length; count++)
{
if (data[count].name == "Deliver")
{
var job_id = data[count].id;
postman.setEnvironmentVariable("service_id", job_id);
var job1_name = data[count].options[0].name;
postman.setEnvironmentVariable("item_name", job1_name);
var job2_id = data[count].options[0].id;
postman.setEnvironmentVariable("item_id", job2_id);
var job3_id = data[count].options[0].options[1].id;
postman.setEnvironmentVariable("svc_optn_optn_id", job3_id);
var job4_name = data[count].options[0].options[1].name;
postman.setEnvironmentVariable("svc_optn_optn_name", job4_name);
}
const data = JSON.parse(responseBody);
data.forEach(item => {
console.log(item.id); // deliver object id.
item.options.forEach(option => {
console.log(`Option Id ${option.id}`); // option id
postman.setEnvironmentVariable("service_id", option.id);
option.options(optionItem => {
if(optionItem.name == 'Toothbrush'){
postman.setEnvironmentVariable("svc_optn_optn_name", optionItem.name);
postman.setEnvironmentVariable("svc_optn_optn_id", optionItem.id);
}
});
});
});
I have a JSON response
{
"nextAction": [{
"userList": [{
"id": 8,
"email": "testemail#gmail.com",
"name": "John Doe"
}],
"buttonLabel": "Finalize Now"
},
{
"userList": [{
"id": 10,
"email": "newemail#gmail.com",
"name": "Test User"
}],
"buttonLabel": "Start Now"
}
]
}
The userList array sometimes contain null object.
I am working on a condition which satisfies the below 3 conditions.
The nextAction array should be non-empty.
The userList array shouldn't contain the null element.
The currentUser should be present in the userList array.
const data = [{
"userList": [{
"id": 8,
"email": "testemail#gmail.com",
"name": "John Doe"
}],
"buttonLabel": "Finalize Now"
},
{
"userList": [{
"id": 10,
"email": "newemail#gmail.com",
"name": "Test User"
}],
"buttonLabel": "Start Now"
}]
function checkForMyNextActions(myNextActions, currentUser) {
const checkUsername = obj => obj.email === currentUser;
return (myNextActions.forEach((myAction, index) => {
(myAction.userList.length &&
myAction.userList.every(userList =>
userList !== null) &&
myAction.userList.some(checkUsername)
)
}))
}
var result = checkForMyNextActions(data, "testemail#gmail.com")
console.log(result)
The expected result is true whereas I get undefined.
You could do this via some & find:
var obj = {
"nextAction": [{
"userList": [{
"id": 8,
"email": "testemail#gmail.com",
"name": "John Doe"
}],
"buttonLabel": "Finalize Now"
}]
}
const getUser = (usr) => obj.nextAction.some(({
userList
}) =>
userList ? (userList.every(userList => userList !== null) &&
userList.find(y => y.email === usr)) : false)
console.log(getUser("testemail#gmail.com")) // true
console.log(getUser("test#gmail.com")) // false
The nice thing about some method is that it returns boolean if one element matches the condition which in our case is the inner find for the email.
You can go little further and make the function accept a field to match on as well like this:
var obj = { "nextAction": [{ "userList": [{ "id": 8, "email": "testemail#gmail.com", "name": "John Doe" }], "buttonLabel": "Finalize Now" }] }
const getUser = (field="email", usr) => obj.nextAction.some(({userList}) =>
userList ? userList.find(y => y[field] === usr): false)
console.log(getUser("email", "testemail#gmail.com")) // true
console.log(getUser("name", "John Doe")) // true
checkForMyNextActions returns undefined because forEach returns undefined. Use map to call a function on each element in an array and return a new array with the return values of the functions. Also the inner function passed to forEach does not return anything.
You can simply use Array.reduce() for this:
const data = [{ "userList": [{ "id": 8, "email": "testemail#gmail.com", "name": "John Doe" }], "buttonLabel": "Finalize Now" }];
function checkForMyNextActions(myNextActions, currentUser) {
const checkUsername = obj => obj.email === currentUser;
return myNextActions.reduce((a,curr)=>{
let bool = curr.userList.length && curr.userList.every(userList =>userList !==null) && curr.userList.some(checkUsername);
return bool && a;
},true) != 0;
}
var result = checkForMyNextActions(data, "testemail#gmail.com")
console.log(result)