filtering const data in vuejs - javascript

i have a vue app with ad group of data.
const data = [
{
name: 'value1',
id: 'id1',
supervisor: true,
},
{
name: 'value2'
id: 'id2',
supervisor: false,
}
]
but i just need to display data for supervisor = true only.
i'd tried to filter it with belows code but it did not work.
const test = data.filter(data => data.supervisor = true);
console.log(test);
can somenone share any reference for me to refer for this filtering function as i new in vue js. or anyone can share their knowledge. because actually i have the data from api which need to be display with some sort of condition.
i have tried using url/api/items?supervisor=true and then i was inform that the API did no support for that kind of way so i need to create a filter function in javascript from data that retrieve from APIs. i'm using above const data =[{...,...}] in this question for it easier to understand.

const test = data.filter(data => data.supervisor === true);
Full working example, since your data was also missing a comma, so the not working part can be from there:
const data = [
{
name: 'value1',
id: 'id1',
supervisor: true,
},
{
name: 'value2',
id: 'id2',
supervisor: false,
}
];
const test = data.filter(data => data.supervisor === true);
console.log(test);

You should use const test = data.filter(data => data.supervisor); instead of > true

Related

Mui-DataTables customBodyRenderLite, render multiple links in one cell

I've also created an issue in their github for further help
I am creating an app with a lot of relationships and with mui-datatables want to create links to different profiles within the cells. Sometimes a single cell may need to contain more than one link otherwise I would use the onCellClick function.
An example of this use case might be Pet owners and their pets (this isn't actually my use-case, just an example).
Say I create a table of Owners and then in one cell is a list of the pet names
Owners
Pet Names
Paige
Sally, Sage, Ember
I've gotten it to where I can push all the names of the animals related to a specific owner to a new array and then join that array to create a string that shows up properly with all the pets listed. When I click on the row I get taken to the owner profile with the onRowClick function which is exactly how I want it
Code Example
const [data, setData] = useState([]);
const [petColumns, setPetColumns] = useState([]);
const [columnData, setColumnData] = useState([]);
const [options, setOptions] = useState({
filter: true,
filterType: 'dropdown',
responsive: 'standard',
rowsPerPage: 10,
resizableColumns: true,
enableNestedDataAccess: '.',
selectableRows: 'none',
onRowClick: (rowData) => {
handleClick(rowData);
}
})
setPetColumns = [
{
name: "id",
label: "Id",
options: {
display: 'excluded',
}
},
{
name: "name",
label: "Owner Name",
},
{
name: "pet",
label: "Pets",
},
]
useEffect(() => {
API.getOwnerData(ownerId)
.then(res => setData(res.data))
.catch(err => console.log(err))
}, [ownerId])
useEffect(() => {
const ownerData = data.map((owner) => {
const petList = []
owner.Pets.forEach((pet) => {
petList.push({
name: pet.name,
})
})
const petObject = {
id: owner.id,
name: `${owner.User.firstName} ${owner.User.lastName}`,
pet: petList.map(p => p.name).join(', '),
}
return petObject
})
setColumnData(ownerData)
}, [data])
const handleClick = (rowData) => {
navigate(`${rowData[0]}`)
}
<MUIDataTable
className={styles.innerTable}
data={columnData}
columns={petColumns}
options={options}
>
</MUIDataTable>
Where I'm running into trouble is that I want to turn each of the pet names that are being listed into a link that will navigate to the pets respective profile when clicked on. I will show some of my attempts to do this and explain what the results were.
ATTEMPT 1
Here I added pet.id to the petList object. This id is used with react-router-dom and Link to travel to the proper profile page for the pet. I then set up a customBodyRender (I tried both customBodyRender and customBodyRenderLite) which is supposed to map through the pet list and create a link with the pet name for each entry and then join together the new link divs.
I'm actually fairly stumped on this because I keep getting "Uncaught TypeError: value.map is not a function". Which makes me think that the value of property is not being recognized as an array. However, I found several StackOverFlow posts where value is treated properly as an array and can be joined together such as here.
I also recognize though that the array in that stack overflow is flat which mine is not but I even added the "enableNestedDataAccess: '.'," to that specific set of options (even though it's already in the general options for the table) just to make sure. I tried some variations of metadata as well but couldn't get that to stick either, I honestly think I'm probably incorporating it wrong.
CODE EXAMPLE - I didn't include the code that remained unchanged
setPetColumns = [
{
name: "id",
label: "Id",
options: {
display: 'excluded',
}
},
{
name: "name",
label: "Owner Name",
},
{
name: "pet",
label: "Pets",
options: {
customBodyRenderLite: (value) => { ****ATTEMPTED customBodyRender TO RENDER THE LINK AND THEN JOIN ****
return (
<>
{value.map((e) => {
<Link to={`/pets/id=${e.id}`} >{e.name}</Link>
}).join(', ')}
</>
)
}
}
},
]
useEffect(() => {
const ownerData = data.map((owner) => {
const petList = []
owner.Pets.forEach((pet) => {
petList.push({
name: pet.name,
id: pet.id ****ID IS ADDED FOR NAVIGATION PURPOSES****
})
})
const petObject = {
id: owner.id,
name: `${owner.User.firstName} ${owner.User.lastName}`,
pet: petList
}
return petObject
})
setColumnData(ownerData)
}, [data])
When I console log columnData I get exactly what I'm expecting
0:
id: "30c9"
name: "Paige"
property: Array(3)
0:
id: "df43"
name: "Sally"
1:
id: "dea4"
name: "Sage"
2:
id: "ger7"
name: "Ember"
ATTEMPT 2
My attempt here was kind of a hail mary, I'd been working trying to get the custom render to work for a long while so I thought I'd go at it from a different direction. I trying to include Link within the petObject that initially worked in providing the plain joined names.
My result of this attempt was that my data table rendered but I got [ object Object ] within the pet Columns if I included return in the .map function or an empty string if there was no return. I honestly didn't really expect this to work but was at a loss of what else to try. When I consoled the columnData it was either [ object Object ] or ""
setPetColumns = [
{
name: "id",
label: "Id",
options: {
display: 'excluded',
}
},
{
name: "name",
label: "Owner Name",
},
{
name: "pet",
label: "Pets",
},
]
useEffect(() => {
const ownerData = data.map((owner) => {
const petList = []
owner.Pets.forEach((pet) => {
petList.push({
name: pet.name,
id: pet.id ****ID IS ADDED FOR NAVIGATION PURPOSES****
})
})
const petObject = {
id: owner.id,
name: `${owner.User.firstName} ${owner.User.lastName}`,
*****TRIED TO INCLUDE LINK WITHIN OBJECT****
pet: petList.map((p) => {
return <Link to=`/pet/id=${p.id} >p.name </Link> ****If return isn't included a blank string is returned****
}).join(', '),
}
return petObject
})
setColumnData(ownerData)
}, [data])
Tech
Version
Material-UI
4.12.3
MUI-datatables
4.1.2
React
17.0.2
browser
Google Chrome

how do I add an item on array of Objects on setState in React?

I am creating arrays of objects and storing it on variables like this:
const nameOption = nameOptions(listHotels);
const estadoOption = stateOptions(listHotels);
const cityOption = cityOptions(listHotels);
my state is currently like this:
selectFilter: [
{ id: 1, type: 'Name'},
{ id: 1, type: 'Estado'},
{ id: 1, type: 'Cidade'},
],
I want to add these variables in a property called "options", like so:
selectFilter: [
{ id: 1, type: 'Name', options: nameOption},
{ id: 1, type: 'Estado', options: estadoOption},
{ id: 1, type: 'Cidade', options: cityOption},
],
how do I do it using the immutable react way?
First store the values to be inserted into a plain object, where the properties match the type values of selectFilter :
const options = {
Name: nameOptions(listHotels),
Estado: stateOptions(listHotels),
Cidade: cityOptions(listHotels)
}
Then merge that with selectFilter into the extended version of it:
this.setState(prevState => ({
selectFilter: prevState.selectFilter.map(filter =>
({...filter, options: options[filter.type]})
)
}));
NB: there is probably a more efficient way to build the options object, since you seem to iterate listHotels for each property. This could probably be done in one sweep using reduce. But without details about what these functions (nameOptions, stateOptions, ...) do there is not much I can offer for that. Look into calling listHotels.reduce.
You can use Object.assign() to duplicate your state into an new object. This object is now mutable. Once done modifying it, you then replace your entire state with the new version. Here is an example of how that could be done.
handleChange= () => {
let mutableState = Object.assign({}, this.state);
mutableState.thingToChange = foo;
this.setState(mutableState);
};
this.setState(({selectFilter}) => (
[
{...selectFilter[0], options: nameOptions},
{...selectFilter[1], options: estadoOptions},
{...selectFilter[2], options: cityOptions},
]
);

Normalizr - is it a way to generate IDs for non-ids entity model?

I'm using normalizr util to process API response based on non-ids model. As I know, typically normalizr works with ids model, but maybe there is a some way to generate ids "on the go"?
My API response example:
```
// input data:
const inputData = {
doctors: [
{
name: Jon,
post: chief
},
{
name: Marta,
post: nurse
},
//....
}
// expected output data:
const outputData = {
entities: {
nameCards : {
uniqueID_0: { id: uniqueID_0, name: Jon, post: uniqueID_3 },
uniqueID_1: { id: uniqueID_1, name: Marta, post: uniqueID_4 }
},
positions: {
uniqueID_3: { id: uniqueID_3, post: chief },
uniqueID_4: { id: uniqueID_4, post: nurse }
}
},
result: uniqueID_0
}
```
P.S.
I heard from someone about generating IDs "by the hood" in normalizr for such cases as my, but I did found such solution.
As mentioned in this issue:
Normalizr is never going to be able to generate unique IDs for you. We
don't do any memoization or anything internally, as that would be
unnecessary for most people.
Your working solution is okay, but will fail if you receive one of
these entities again later from another API endpoint.
My recommendation would be to find something that's constant and
unique on your entities and use that as something to generate unique
IDs from.
And then, as mentioned in the docs, you need to set idAttribute to replace 'id' with another key:
const data = { id_str: '123', url: 'https://twitter.com', user: { id_str: '456', name: 'Jimmy' } };
const user = new schema.Entity('users', {}, { idAttribute: 'id_str' });
const tweet = new schema.Entity('tweets', { user: user }, {
idAttribute: 'id_str',
// Apply everything from entityB over entityA, except for "favorites"
mergeStrategy: (entityA, entityB) => ({
...entityA,
...entityB,
favorites: entityA.favorites
}),
// Remove the URL field from the entity
processStrategy: (entity) => omit(entity, 'url')
});
const normalizedData = normalize(data, tweet);
EDIT
You can always provide unique id's using external lib or by hand:
inputData.doctors = inputData.doctors.map((doc, idx) => ({
...doc,
id: `doctor_${idx}`
}))
Have a processStrategy which is basically a function and in that function assign your id's there, ie. value.id = uuid(). Visit the link below to see an example https://github.com/paularmstrong/normalizr/issues/256

Unable to render tree like structure in Angular?

Hi I am developing web application in Angular 5. I am trying to display tree like structure. I am following the
https://github.com/500tech/angular-tree-component/blob/master/example/cli/src/app/async/async.component.ts and
https://angular2-tree.readme.io/docs/async-data-1
In the above example they have given some data and my application works with it. In real time I am using some other data and converting it to exactly the format in the example they have given.
Below is my example.
let results = JSON.parse('{"userid":"e75792f8-cfea-460e-aca2-07a778c92a7c","tenantid":"00000000-0000-0000-0000-000000000000","username":"karthik","emailaddress":"john#krsars.onmicrosoft.com","isallowed":false,"userroles":[{"userroleid":"b81e63d1-09da-4aa0-af69-0f086ddb20b4","userid":"e75792f8-cfea-460e-aca2-07a778c92a7c","roleid":"85d2f668-f523-4b64-b177-b1a78db74234","tenantappid":1,"validfrom":"2018-01-24T00:00:00","validto":"2018-01-24T00:00:00","isactive":true}]}');
for (const key in results) {
if (results[key] instanceof Array) {
const containerTyp2 = {name: '', hasChildren: false,};
containerTyp2.name = key;
containerTyp2.hasChildren = true;
this.nodes.push(containerTyp2);
} else {
const object = {name: ''};
const containerTyp1 = {name: '', children: []};
object.name = results[key];
containerTyp1.name = key;
containerTyp1.children.push(object);
this.nodes.push(containerTyp1);
}
}
console.log(this.nodes);
Below is the sample data from application example.
this.nodes = [
{
name: 'root1',
children: [
{ name: 'child1' }
]
},
{
name: 'root2',
hasChildren: true
},
{
name: 'root3'
}
];
I am converting my raw data to same format to the example above. When I display both data in console both looks similar except id field. Whenever i display example data, I can see id field get added with random value but explicitly they are not adding. Below is the console of example data.
Below is the console of raw data.
Can someone help me to figure out the issue? I am not able to identify what is the reason not to display raw data. Any help would be appreciated. Thank you.
I fixed this issue by adding below line at the end of for loop.
let results=data;
for (const key in results) {
if (results[key] instanceof Array) {
const containerTyp2 = {name: '', hasChildren: false,};
containerTyp2.name = key;
containerTyp2.hasChildren = true;
this.nodes.push(containerTyp2);
} else {
const object = {name: ''};
const containerTyp1 = {name: '', children: []};
object.name = results[key];
containerTyp1.name = key;
containerTyp1.children.push(object);
this.nodes.push(containerTyp1);
}
this.tree.treeModel.update();

Manipulating data in nested arrays in Redux with immutable.js

So, I've been working on making an APP in React Native for which i have programmed a RESTFul API in Java, which returns some data in JSON format. I will have a datastructure that looks something like this - it is also the initial state for this Reducer, I have simply deleted some of the values as they are irrelevant:
categories: [{
id: 1,
name: '',
image: '',
subcategories: [
{
name: '',
id: 1,
products: [{
name: '',
description: 'This is a good product',
id: 55,
quantity: 4
}, {
name: '',
description: 'This is a good product',
id: 3,
quantity: 0
}]
},
{
name: '',
id: 2,
products: [{
name: '',
description: 'This is a good product',
id: 4,
quantity: 0
}]
}]
}, {
id: 2,
name: '',
image: '',
subcategories: [
{
name: '',
id: 3,
products: [{
name: '',
description: 'This is a good product',
id: 15,
quantity: 0
}]
}
]
}]
I will be saving this in my Redux store but where i struggle is when I have to update the quantity of a certain product with only the products id.
So far I've found a solution using immutable.js but it is quite ugly and I'm really unsure if this is the way to go.
I've searched for solutions but have not yet found one with a solution without normalizing the datastructure. For now I want to see if I can avoid normalizing the data, as I want to keep the same format for posting stuff back to the server. (and for learning purposes)
My solution in my Reducer with immutable.js looks like this:
case types.ADD_PRODUCT:
const oldState = fromJS(state).toMap();
var findCategoryIndex = oldState.get('categories').findIndex(function (category) {
return category.get("subcategories").find(function (subcategories) {
return subcategories.get("products").find(function (product) {
return product.get("id") === action.productId;
})
})
})
var findSubcategoryIndex = oldState.getIn(['categories', findCategoryIndex.toString()]).get('subcategories').findIndex(function (subcategory) {
return subcategory.get("products").find(function (product) {
return product.get("id") === action.productId;
});
})
var findProductIndex = oldState.getIn(['categories', findCategoryIndex.toString(), 'subcategories', findSubcategoryIndex.toString()]).get('products').findIndex(function (product) {
return product.get("id") === action.productId;
})
var newState = oldState.setIn(['categories', findCategoryIndex.toString(),
'subcategories', findSubcategoryIndex.toString(), 'products', findProductIndex.toString(), 'quantity'],
oldState.getIn(['categories', findCategoryIndex.toString(), 'subcategories', findSubcategoryIndex.toString(), 'products', findProductIndex.toString(), 'quantity'])+1);
const newStateJS = newState.toJS();
return {...state, categories: [...newStateJS.categories]}
I know all this may seem overcomplicated for the case, but I am simply trying to learn different approaches to this as I am very new to everything that has to do with JavaScript.
I am not looking for optimization on the data format itself, but I am looking for ways to manipulate data in nested arrays in Redux
I hope to get some good feedback on this and hopefully find out if I am on the right track :)
EDIT: It works with spread operators aswell without using Immutable.js, but I don't really understand what the difference is. Is there a performance difference and why choose one over the other?
case types.ADD_PRODUCT:
return {
...state,
categories:[...state.categories.map(category => ({...category,
subcategories:[...category.subcategories.map(subcategory => ({...subcategory,
products:[...subcategory.products.map(product => product.id === action.productId ? {...product, quantity: product.quantity+1} : product)]}))]}))]
}
When things the data to become a bit too deep, you can still use helper like Immutable.js Map. I am not sure this is the correct way to use Immutable.js since I am also experimenting it. It lets you return new state in a less verbose way like this :
import { fromJS } from 'immutable';
export default function reducer(state = initialState, action) {
const iState = fromJS(state);// Immutable State
switch (action.type) {
case type.ACTION:
return iState.setIn(['depth1','depth2', 'depth3'], 'foobar').toJS()
// return a copy of the state in JavaScript
// {depth1: {depth2: {depth3: 'foobar'} } }
default:
return state;
}
and from what I heard, using Immutable is more performant but it adds an another dependency to your project. Careful tough, if you are using combineReducers(reducers), it expects to be pass a plain object, so be sure to pass a plain object and not an Immutable object.
You said you are not specifically looking for optimization on the data format itself. Correct me if I am wrong, I think normalizr will help you to gain in flatness and be easier to update your store

Categories

Resources