Search object within object and get the key - javascript

I have an object router shown below. lets say I have another var x = "/podcast" and I want to find which key this variable x would reside. For example in this case I want to return the value "M2"
How can I search this object router and it's sub-objects to return the appropriate key?
Thanks!
var router = {
M1: {
url: "/",
description: "",
title: "",
image: "",
},
M2: {
url: "/podcast",
description: "",
title: "",
image: "",
},
M3: {
url: "/about",
description: "",
title: "",
image: "",
},
};

You can use Object.keys() to get Array of object keys then .filter(), here is a working snippet:
const search = '/podcast';
const router = {
M1: {
url: "/",
description: "",
title: "",
image: ""
},
M2: {
url: "/podcast",
description: "",
title: "",
image: ""
},
M3: {
url: "/about",
description: "",
title: "",
image: ""
}
};
const foundElement = Object.keys(router).filter((el) => router[el].url === search);
console.log(foundElement[0]);

To get your keys you use Object.keys(object)
To search the key you can use filter() or find().
To apply the condition you define callback function inside filteror find.
In my case, I used find function :
const foundElement = (router, searchableValue) => {
const founded = Object.keys(router).find(
(value) => router[value].url === searchableValue
);
return founded === undefined ? "Key not found" : founded;
};
const searchableValue = "/podcast";
console.log(foundElement(router, searchableValue));

Related

Filtering an object by multiple arguments(inputs)

I have a lot of inputs, after which my object is supposed to filter, I can hardcode it, but there is probably a smarter way to do it
Filter state :
const [filters, setFilters] = useState<FiltersType>({
login: "",
name: "",
surrname: "",
});
Example data:
const data: UserRow[] = [
{
key: "1",
login: "John#gmail.com",
name: "John",
surrname: "Smith",
role: ["user"],
},
{
key: "2",
login: "Andrew#gmail.com",
name: "Andrew",
surrname: "Johnson",
role: ["user"],
},
];
data.filter((e) => {
if (
(!filters.name || e.name.includes(filters.name)) &&
(!filters.surrname || e.surrname.includes(filters.surrname)) &&
(!e.login ||
e.login.toLowerCase().includes(filters.login.toLowerCase()))
) {
return true;
}
return false;
})
For example, it can be done like this, but as you can see it looks bad and scales poorly when adding new fields, I tried to simplify it using "Object.entries()", but ultimately failed :(. What is the best pattern for such a problem?
You should use some() (logical OR for all the conditions) or every() (logical AND for all the conditions) in combination with filter().
const data = [
{
key: "1",
login: "John#gmail.com",
name: "John",
surrname: "Smith",
role: ["user"],
},
{
key: "2",
login: "Andrew#gmail.com",
name: "Andrew",
surrname: "Johnson",
role: ["user"],
},
];
const filter = {
login: "",
name: "",
surrname: "",
};
const filters = Object.entries(filter);
const filtered = data.filter((user) =>
filters.some(
([key, value]) =>
user[key] && user[key].toString().toLowerCase().includes(value)
)
);
console.log(filtered);
Use some() if you want to include the result if any of the filter conditions is met and use every() if you want to only include a result if all filter conditions are met.
The above will work for simple filters. You can however extend the solution using typeof() or Array.isArray() function etc. to process different types like arrays, nested objects etc. accordingly.

rethinkDB: get first key name in an object

I'm just starting with rethinkDB query lang and don't understand how to select the first key (name).
In this case I would be the object notes.
I did it with Object.keys(t)[0]; tries that just returns me args, what am I doing wrong?
{
id: "mission#0",
info:
"Tokyo",
**//how to get the value of content ?**
note: {
"note#032b8836-f647-4165-9ec9-fc22769f3ffa": {
content: "hello world",
context: "all",
glyphId: "glyph#default",
id: "note#032b8836-f647-4165-9ec9-fc22769f3ffa",
meta: {
context: null,
createdAt: 1624044683953,
id: "note#032b8836-f647-4165-9ec9-fc22769f3ffa",
links: null,
parentEntity: "mission#0b1cd61d-bb36-4cf8-8f3d-9cc9b14ff054",
references: { glyphId: "glyph" },
rootAggregateId: "mission#0b1cd61d-bb36-4cf8-8f3d-9cc9b14ff054",
rootAggregatePath: [
"private",
"notes",
"note#032b8836-f647-4165-9ec9-fc22769f3ffa",
],
status: "published",
summaries: {
description: "hello world",
glyph: "bookmark",
glyphColor: "base",
info: "hello world",
},
type: "note",
values: null,
version: 0,
},
},
}
function* extract(next) {
const q = r
.db("test")
.table("mission")
.getAll(true, { index: "recurrenceEnabled" })
.filter((mission) => mission("meta")("status").eq("published"))
.map((m) => {
let t = m("private")("notes");
let p = Object.keys(t)[0];
return {
note: t,
id: m("id"),
info: m("meta")("summaries")("info"),
};
});
return yield q.run(con, next);
}
Thank you for the reading !

Spread operator not working in method map in Express.js

I get data from database using sequelize in Express.js query:
const users = await models.users.findAll({
deleted: 0,
});
Returned this:
[
{
"id": 1,
"name": "test",
"logo": "1588863296261.png",
}
]
Now I need add full adress to "logo":
http://127.0.0.1:3000/public/logo/1588863296261.png
So I using method map:
const dataUsers = users.map(user => ({
...user,
logo: user.logo ? `http://${req.headers.host}/public/logo/${user.logo}` : null,
}));
res.status(200).json(dataUsers);
dataUsers return null Object, but when I remove spread operator and I replace it with this:
id: user.id,
name: user.name,
description: user.description,
logo: user.logo ? `http://${req.headers.host}/public/logo/users/${user.logo}` : null,
Then it work correctly. Why spread operator does not work in this example ?

JSON Stringfy only a few properties

I have this object:
{
name: "",
email: "",
phone: "",
protocol: "",
area: "",
subject: "",
message: "",
validation: this.validator.valid()
}
I wanna convert it to JSON, but I do not want the validation property on it.
I've already tried the following:
const test = JSON.stringify(this.state);
delete test.validation;
Any other approach?
JSON.stringify takes a replacer callback you can use. The replacer function takes a key k and the value v being stringified as parameters. Returning undefined will have the effect of not including the key in the final result:
state = {
name: "",
email: "",
phone: "",
protocol: "",
area: "",
subject: "",
message: "",
validation: "some val"
}
const test = JSON.stringify(state, (k, v) => k != 'validation' ? v : undefined);
console.log(test)
Note: used like this it will remove the validation key from any child objects as well, which may or may not be what you want.
It will work.
const { validation, ...rest } = this.state;
JSON.stringify(rest);
UPDATE - I found a different solution
It's very simple, in fact. I've discovered the solution here.
The following lines solved my problem:
const formSubmit = JSON.stringify(this.state, ['name', 'email', 'phone', 'protocol','area','subject', 'message']);
If you put an undefined, JSON.stringify will skip it:
const yourState = {
name: "",
email: "",
phone: "",
protocol: "",
area: "",
subject: "",
message: "",
validation: true,
}
const copy = {
...yourState,
validation: undefined,
};
console.log(JSON.stringify(copy));
Also, you can not perform a delete from JSON.stringify because it is a string an not an object literal.

Find JSON index based on child key value using Javascript

I have the below JSON which controls the flow of the pages in my application. To navigate between screens manually I use the index of a page. If I were to link to Page 1 I would use the index '0'. I would like to be able to navigate using the id instead. So I could use S010_010 to navigate. Unfortunately the navigation function of the app is used by multiple elements and cannot be changed completely so I am looking for a method that can take the id and return the index from flows.
var flows = {
"default": [{
theme: "theme1",
events: "touchstart",
easingSlideIn: "transition.fadeIn",
easingSlideOut: "transition.fadeOut",
easingRef: "transition.perspectiveRightIn",
easingPop: "transition.flipYIn"
},
{
id: "S010_010", //0
description: "",
chapter: "01",
ref: ""
},
{
id: "S020_010", //1
description: "",
chapter: "01",
ref: ""
},
{
id: "S030_010", //2
description: "",
chapter: "01",
ref: ""
},
]
};
This is an example of how I currently retrieve the id using the index:
this.options.flow[screen +1].id
You can use for-in to iterate and return the index if id matches with that of method's. It is also recommended to use for-of but you end up descructing something like this for(const [index, value] of flows.default.entries()) to fetch index hence used for-in
let flows = {
"default": [{
theme: "theme1",
events: "touchstart",
easingSlideIn: "transition.fadeIn",
easingSlideOut: "transition.fadeOut",
easingRef: "transition.perspectiveRightIn",
easingPop: "transition.flipYIn"
},
{
id: "S010_010", //0
description: "",
chapter: "01",
ref: ""
},
{
id: "S020_010", //1
description: "",
chapter: "01",
ref: ""
},
{
id: "S030_010", //2
description: "",
chapter: "01",
ref: ""
},
]
};
let getFlowByID = (id) => {
for(let eachFlowIndex in flows.default){
if(flows.default[eachFlowIndex].id == id){
return eachFlowIndex;
}
}
}
console.log(getFlowByID("S030_010")); // gets S030_010 index
There is no specific method, but you can create your own inverted index
var invertedIndex = {};
flows.default.forEach((elem, index) => {
if(elem.id != null) {
invertedIndex[elem.id] = index - 1;
}
})
//then you can use the id for the lookup as
invertedIndex['S030_010']
We use for in cycle to iterate through our array of objects and return the index if id was found.
ES5 solution
var flows =
{
"default":
[
{
theme: "theme1",
events: "touchstart",
easingSlideIn: "transition.fadeIn",
easingSlideOut: "transition.fadeOut",
easingRef: "transition.perspectiveRightIn",
easingPop: "transition.flipYIn"
},
{
id: "S010_010", //0
description: "",
chapter: "01",
ref: ""
},
{
id: "S020_010", //1
description: "",
chapter: "01",
ref: ""
},
{
id: "S030_010", //2
description: "",
chapter: "01",
ref: ""
}
]
};
function getIndex(id)
{
var i = 0,
objs = flows.default;
for (i in objs)
if (objs[i].id == id)
return +i - 1
}
console.log(getIndex('S010_010')); //0
ES6 solution
We use Array.find function to iterate through our array, save the index if id was found and than return it. In the case if it is not found it returns -1. But unfortunatelly this solution isn't shorter than my ES5 solution.
var flows =
{
"default":
[
{
theme: "theme1",
events: "touchstart",
easingSlideIn: "transition.fadeIn",
easingSlideOut: "transition.fadeOut",
easingRef: "transition.perspectiveRightIn",
easingPop: "transition.flipYIn"
},
{
id: "S010_010", //0
description: "",
chapter: "01",
ref: ""
},
{
id: "S020_010", //1
description: "",
chapter: "01",
ref: ""
},
{
id: "S030_010", //2
description: "",
chapter: "01",
ref: ""
}
]
};
let getIndex = (id) => {
let ret = -1;
flows.default.find((elem, index) => {
if(elem.id == id)
ret = index - 1
});
return ret
};
console.log(getIndex('S010_010')); //0

Categories

Resources