最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - MUI React Dropdown prop passable filter - Stack Overflow

programmeradmin4浏览0评论

I am trying to create a filter setup that I can add to a Material-UI dropdown that I can pass via props of what specified value of specified variable so I can reused the filter on any of my dropdowns, so I can declare different variable and different values for each.

The API used to populate the Dropdown is returning a value set similar to this:

0: {id: 7, name: 'Time', isOnHold: 0}
1: {id: 8, name: 'Temperature', isOnHold: 1}

I would like to pass the variable as filterVar, and the value of that variable as filterVal so I can select different variable for different dropdowns. In the example below I want to filter out options where isOnHold = 1.

Here is what I have attempted:

As called from the form:

<Dropdown
    onChange={handleInputChange}
    label='Parameter'
    name='parameterId'
    value={values.parameterId}
    prompt='Select A Parameter...'
    url={paramUrl} 
    filterVar={'isOnHold'}
    filterVal={1}
/>

The Dropdown component:

import * as React from 'react';
import axios from 'axios';
import { FormControl, FormHelperText, InputLabel, Select, MenuItem } from '@material-ui/core';

function Dropdown(props) {
  const { filterVar, filterVal, label, name, onChange, prompt, value, url, ...other } = props;
  const [options, setOptions] = React.useState([]);

  React.useEffect(() => {
    const fetchData = async () => {
      const res = await axios.get(url);
      setOptions(res.data);
    };
    fetchData();
  }, []); 
 
  return(
    <FormControl >
        <InputLabel>{label}</InputLabel>
        <Select
           onChange={onChange}
           value={value} 
           name={name}
           {...other}
         >
         <MenuItem>{prompt}</MenuItem>
         {options.filter(option => (option.filterVar).includes(filterVal)).map((option, id) => (
           <MenuItem
              key={option.id}
              value={option.id}
           >
              {option.name}
           </MenuItem>
        ))}
      </Select>
   </FormControl>
  );
}

export default Dropdown;

As it right now, I can't get this to work, I keep getting an error of:

Uncaught TypeError: Cannot read properties of undefined (reading 'includes')

, so if anyone know how I can fix this, or had a better want to handle filtering the options, it would be greatly appreciated. Something likes passing option.isOnHold === 1.

I am trying to create a filter setup that I can add to a Material-UI dropdown that I can pass via props of what specified value of specified variable so I can reused the filter on any of my dropdowns, so I can declare different variable and different values for each.

The API used to populate the Dropdown is returning a value set similar to this:

0: {id: 7, name: 'Time', isOnHold: 0}
1: {id: 8, name: 'Temperature', isOnHold: 1}

I would like to pass the variable as filterVar, and the value of that variable as filterVal so I can select different variable for different dropdowns. In the example below I want to filter out options where isOnHold = 1.

Here is what I have attempted:

As called from the form:

<Dropdown
    onChange={handleInputChange}
    label='Parameter'
    name='parameterId'
    value={values.parameterId}
    prompt='Select A Parameter...'
    url={paramUrl} 
    filterVar={'isOnHold'}
    filterVal={1}
/>

The Dropdown component:

import * as React from 'react';
import axios from 'axios';
import { FormControl, FormHelperText, InputLabel, Select, MenuItem } from '@material-ui/core';

function Dropdown(props) {
  const { filterVar, filterVal, label, name, onChange, prompt, value, url, ...other } = props;
  const [options, setOptions] = React.useState([]);

  React.useEffect(() => {
    const fetchData = async () => {
      const res = await axios.get(url);
      setOptions(res.data);
    };
    fetchData();
  }, []); 
 
  return(
    <FormControl >
        <InputLabel>{label}</InputLabel>
        <Select
           onChange={onChange}
           value={value} 
           name={name}
           {...other}
         >
         <MenuItem>{prompt}</MenuItem>
         {options.filter(option => (option.filterVar).includes(filterVal)).map((option, id) => (
           <MenuItem
              key={option.id}
              value={option.id}
           >
              {option.name}
           </MenuItem>
        ))}
      </Select>
   </FormControl>
  );
}

export default Dropdown;

As it right now, I can't get this to work, I keep getting an error of:

Uncaught TypeError: Cannot read properties of undefined (reading 'includes')

, so if anyone know how I can fix this, or had a better want to handle filtering the options, it would be greatly appreciated. Something likes passing option.isOnHold === 1.

Share Improve this question edited Mar 19 at 0:30 Yong Shun 51.8k6 gold badges35 silver badges63 bronze badges asked Mar 14 at 19:58 MtullisMtullis 611 silver badge6 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 1

Since you are sending the property name to the filterVar variable, you should use the property accessor with the Bracket notation ([<property name>]) instead of Dot notation as filterVar is not the property in the option object.

Also note that from your attached data, the isOnHold is an integer instead of string. Hence, you should not use includes as it is a String function; instead, use the equal operator ===. Otherwise, you need to cast/convert isOnHold to string.

Note that the <String>.includes("<substring>") should be used when checking the string value contains the substring.

{options
  .filter((option) => option[filterVar] === filterVal)
  .map((option, id) => (
      <MenuItem key={option.id} value={option.id}>
        {option.name}
      </MenuItem>
  ))}

Or

{options
  .filter((option) => option[filterVar].toString().includes(filterVal))
  .map((option, id) => (
      <MenuItem key={option.id} value={option.id}>
        {option.name}
      </MenuItem>
  ))}

Demo @ StackBlitz

发布评论

评论列表(0)

  1. 暂无评论