Not able to save object value in Angular component - javascript

This is component class for example:
export class AppComponent {
categories = {
country: [],
author: []
}
constructor(){}
getOptions(options) {
options.forEach(option => {
const key = option.name;
this.categories[key].push(option.value);
})
}
}
On clicking a button, I am calling getOptions(options) from different component. The structure of options looks like:
options = [
{name: 'country', value: 'Germany'},
{name: 'author', value: 'Franz Kafka'}
]
So now the value of this.categories will get updated, so now:
this.categories[country] = ["Germany"]
this.categories[author] = ["Frank Kafka"]
Value of options changes every time on clicking the button. When I am sending new options value such as:
options = [
{name: 'country', value: 'Japan'},
{name: 'author', value: 'Masashi Kishimoto'}
]
Old value for this.categories[country] is not getting saved for some reason. The new value for this.categories[country] should be ["Germany, "Japan"] but I am getting only ["Japan"] in the array.

I don't seems like the code is alright, even I tried through Javascript. What I can suggest is try checking the truthy value of options.value. It could be a possibility that there is some entry with no value options.
let categories = {
country: [],
author: []
}
let options = [
{name: 'country'},
{name: 'author', value: 'Franz Kafka'},
{name: 'country', value: 'Japan'},
{name: 'author', value: 'Masashi Kishimoto'}
]
options.forEach(option => {
const key = option.name;
console.log(key);
if(option.value)
categories[key].push(option.value);
})
console.log(categories);

Related

React issues in setting a state object

I have the following code to set some dropdown state in my app.
let myFieldStatusDropdown = [];
let myFieldStatus = {};
const [myCriteria, setMyCriteria] = useState({
myFieldStatus: myFieldStatus?.value,
myFieldStatusDropdown: myFieldStatusDropdown
});
if (myContextData.myCriteria?.myFieldStatus) {
setMyCriteria({
...myCriteria,
myFieldStatus: myContextData.myCriteria?.myFieldStatus
});
} else {
setMyCriteria({
...myCriteria,
myFieldStatus: myCriteria.myFieldStatusDropdown[0]
});
}
myFieldStatusDropdown is an array like below and myFieldStatus is an object which is one of the options from it
[
{
code: 'Select',
value: 'Select'
}, {
code: 'AA',
value: 'A 1'
}, {
code: 'BB',
value: 'B 1'
}
]
For some reason, myFieldStatus is not getting set properly. Is there some issue in the way I am setting the same ?

Sort array object based on another array in javascript

How can i sort and rearrange an array that looks like this
fields = [
{
uid: '2c2162cc-37d0-f1e3-96c2-6d9ccb50f38d',
field: new ObjectId("627f816d8443318c6aaa1220"
},
{
uid: '2aa60f96-135b-e179-2b46-516c87a877cc',
field: new ObjectId("6283cb3ca573a56e11587c46"),
}
]
to match the arrangement of this array:
order = [ '6283cb3ca573a56e11587c46', '627f816d8443318c6aaa1220' ]
Here is the output I’m looking for:
[
{
uid: '2aa60f96-135b-e179-2b46-516c87a877cc',
field: new ObjectId("6283cb3ca573a56e11587c46"),
},
{
uid: '2c2162cc-37d0-f1e3-96c2-6d9ccb50f38d',
field: new ObjectId("627f816d8443318c6aaa1220"),
}
]
findIndex and sort but I am very confused
fields.sort((a: any, b: any) => order.indexOf(a.field) - order.indexOf(b.field)) // It does not work
You need to use sort method on the array. And then compare the index of field on the order array.
const data = [
{
uid: '2aa60f96-135b-e179-2b46-516c87a877cc',
field: "6283cb3ca573a56e11587c46",
value: 'test val 6'
},
{
uid: '2c2162cc-37d0-f1e3-96c2-6d9ccb50f38d',
field: "627f816d8443318c6aaa1220",
value: ''
}
]
const order = [ '6283cb3ca573a56e11587c46', '627f816d8443318c6aaa1220' ];
data.sort((a,b) => order.indexOf(a.field) - order.indexOf(b.field));
console.log(data);
Notice: ObjectId class is not defined here, so I changed it to string here for simplicity.

Filter array using multiple keys

I'm trying to render grid with multiple toggling filters. I'm Using react hooks.
This is data array:
const items = [
{
name: 'hotel1',
type: 'hotel'
},
{
name: 'bar1',
type: 'bar'
},{
name: 'entertainment1',
type: 'entertainment'
},{
name: 'equipment1',
type: 'equipment'
},
{
name: 'shop1',
type: 'shop'
}
]
const initialFilters = [
{
id: 1,
active: false,
type: 'bar'
},
{
id: 2,
active: false,
type: 'shop'
},
{
id: 3,
active: false,
type: 'hotel'
},
{
id: 4,
active: false,
type: 'entertainment'
},
{
id: 5,
active: false,
type: 'equipment'
},
];
const [data, setData] = useState(items);
const [filterItems, setFilteredItems] = useState(initialFilters);
currently I'm filtering with single key that is passed
const mainFilter = (key) => {
setData(items.filter(x => x.type === key));
}
and filter buttons with grid item names are rendered:
return (
<div>
<ul>
{filterItems.map(x =>
<li key={x.type}><a
className={x.active == true ? 'active' : ''}
onClick={() => mainFilter(x.type)}>
{x.type}
</a></li>
)}
</ul>
<div>{data.map(item => <div>{item.name}</div>}</div>
</div>
)
I need to get the functionality where when pressed for example shop filter, it should only leave items with type shop. if you press bar filter, it should only leave items with bar an shop and it should work all the way to all 5 filters.
if none are selected, it should show full array.
I've tried converting logic from this:
https://gist.github.com/jherax/f11d669ba286f21b7a2dcff69621eb72#file-filterplainarray-js
but no luck yet
You can use the function every for checking if all flags have value false
This code snippet, have an initialFilter with all the flags equal to false
const items = [{name: 'hotel1',type: 'hotel'},{name: 'bar1',type: 'bar'}, {name: 'entertainment1',type: 'entertainment'}, {name: 'equipment1',type: 'equipment'},{name: 'shop1',type: 'shop'}];
const initialFilters = [{id: 1,active: false,type: 'bar'},{id: 2,active: false,type: 'shop'},{id: 3,active: false,type: 'hotel'},{id: 4,active: false,type: 'entertainment'},{id: 5,active: false,type: 'equipment'}];
let allFalse = initialFilters.every(({active}) => !active);
if (allFalse) console.log(items);
Otherwise, you can use the function filter along with the function some:
This code snippet has as active shop and entertainment
const items = [{name: 'hotel1',type: 'hotel'},{name: 'bar1',type: 'bar'}, {name: 'entertainment1',type: 'entertainment'}, {name: 'equipment1',type: 'equipment'},{name: 'shop1',type: 'shop'}];
const initialFilters = [{id: 1,active: false,type: 'bar'},{id: 2,active: true,type: 'shop'},{id: 3,active: false,type: 'hotel'},{id: 4,active: true,type: 'entertainment'},{id: 5,active: false,type: 'equipment'}];
let fltered = items.filter(({type}) => initialFilters.some(({type: t, active}) => t === type && active));
console.log(fltered);
You can store the selected keys and then sort by checking if they are included:
const mainFilter = (keys) => {
setData(items.filter(x => keys.includes(x.type)));
}
This implementation would need a change in your onClick function - instead of calling a function with the key you'll need to store the keys.

How to search within the nested array of objects in javascript?

i want to search a for a string say for example "hello" within 'name' in array of objects. The data structure is like the one below,
[{name:'hello', value: 'value', children: [{ name:'world', value: 'something'}]},
{name:'somename', value: 'value2', children: [{name: 'hello', value: 'value3', children: [{name: 'anothername', value: 'value4'}]},
{name: 'new', value: 'value5'}];
So from the above mentioned data structure, if the search query is say 'hello' i want to check through 'name' field of each object. also check within children 'name' field of each object. Some object may or may not have children and nested children too. I want to retreive the objects that have matched the search query.
For example if my search query is 'hello' then the expected output is as below,
[{name:'hello', value: 'value', children: [{ name:'world', value: 'something'}]},
{name:'somename', value: 'value2', children: [{name: 'hello', value: 'value3', children: [{name: 'anothername', value: 'value4'}]},
i have tried using the below search method but that doesnot search within children and nested children.
search = (query, listitems => {
if (!query) {
return listitems;
}
query = query.toLowerCase();
const results = [];
let counter;
let childcounter;
listitem.forEach((listitem) => {
counter = 0;
childcounter = 0;
if (listitem['name'].toLowerCase().indexOf(query) > -1)
{
counter++;
if (listitem.children)
{
listitem.children.forEach ((child) => {
if (child['name'].toLowerCase().indexOf(query) > -1)
childcounter++;
});
}
listitem.counter = counter;
listitem.childcounter = childcounter;
results.push(listitem);
}
return result
});
How can i do it. could someone help me with it. Thanks.

Filtering a list of objects by a child array in Angular 2

I have data that looks like this
[
{id: 1234,
Name: 'John',
Tags: ['tag1', 'tag2']
},
{id: 1235,
Name: 'Mike',
Tags: ['tag1', 'tag3']
}
]
I want to be able to type into a search bar and filter the data to search for related tags. There was a built in filter pipe for this in angular 1 but it looks like it has been removed in angular 2. I've been looking into custom pipes but the only way I can think to do it is with a nested loop that loops over all of the objects then loops through the tags. Am I thinking about this wrong. Is there an easier way to do this or a built in function that would work for this?
You can just use normal javascript APIs to get that behaviour:
data = [
{id: 1234,
Name: 'John',
Tags: ['tag1', 'tag2']
},
{id: 1235,
Name: 'Mike',
Tags: ['tag1', 'tag3']
}
];
filterDataByTag(searchTerm: string) {
// filter the data array, based on some condition
return this.data.filter(item => {
// only include an item in the filtered results
// if that item's Tags property includes the searchTerm
// includes is a built in array method in ES2016
return item.Tags.includes(searchTerm);
});
}
In my example, i'm harding coding the data, but you can adjust to suit your situation. The key point is the function returns a filtered list of the data based on the searchTerm, so you can just call this method each time you want to refresh your filtered list (for eg on the input event of your search field)
You should reorganize data into a reverse index store :
export interface StoreData {
Tag: string;
Peoples: People[] = [];
}
const store: StoreData[] = [];
export interface People {
id: number;
Name: string;
Tags: string[];
}
loadPeopleStore(peoples: People) {
peoples.forEach(p => {
p.Tags.forEach(t => {
let storeData = store.filter(d => d.Tag === t);
if(storeData.length == 1) {
storeData[0].Peoples.push(p);
} else {
store.push({Tag: t, Peoples[p]});
}
}
}
}
initYourPipe() {
let peoples: People[] = [
{id: 1234,
Name: 'John',
Tags: ['tag1', 'tag2']
},
{id: 1235,
Name: 'Mike',
Tags: ['tag1', 'tag3']
}
]
this.loadPeopleStore(peoples);
}

Categories

Resources