Material UI Select not showing options - reactjs

I have a Component where in the componentDidMount method I fetch information from the backend and put it on the state of my component. However I have to change the response in order to use the objects coming from the backend on the Select Component from material UI.
I do it like this:
var toAdd = []
axios.get(...).then(response.data.forEach(p => toAdd.push({id: p.name, value: p.name}))})
...
this.setState({schemas: toAdd})
Then, on render method I send schemas from state to the form component. The form itself has a set of inputfields with the select component as well.
I have the following warning:
Material-UI: You have provided an out-of-range value undefined for the select (name="schema") component.
Consider providing a value that matches one of the available options or ''.
The available values are "".
I did console.log and the first value I get is an array [] but with objects inside. After I write something on the input fields, the array changes to [{...}] and then the Select can show the options I wanted. The first array [] is not empty, if I open it on console there is one object inside. The same goes for [{...}]. Is there something I am doing wrong?

why don't you use the component state in order to get the data at the time when you get it from the API like this.
state={toAdd:[]}
then while fetching data you just set your state like this
this.setState({toAdd:... response.data.map(v=> {return{id:v.name,value:v.value}})

Related

React - How do you use onlyFetch prop from Opengraph-react?

I am using https://www.npmjs.com/package/opengraph-react
It says if the prop onlyFetch is supplied then no card will display, but instead the results from opengraph will be passed as props to the components children.
However, I do not know how to get hold of the data?
My code is
<OpengraphReactComponent
site={comment.url}
appId={"myapistring"}
size={'small'}
onlyFetch={'true'}
/>
The console shows data from their console.log but I can't work out a way to access the data returned?
I have tried console.log(this.props.children) within the component which is just empty

React-select facing multiple errors when implementing select all/unselect all with initial loaded values

I'm trying to implement a react-select component that has the Select All function with initial loaded values from an API.
After I selected the options, it will send the selected options to it's parent component, App.js in this case with the method getEmployeeVisibility.
The select works if there is no initial loaded values, but when I have some initial values that are loaded to the select, there are a few problems that I'm facing:
I have to double click to select an option after the initial click
If there's only one initial loaded option , I will get the valueRef.current.some is not a function error when opening the input options
If I deselect everything, I will get the Cannot read property 'toString' of null error in App.js.
What is the correct way to load initial values to the select in this case?
Here is my codesandbox for reference:

How to render saved data in a form so I can be edited again?

So I have a Create Order page where you can add a part number, quantity, etc... and then you can click Save where it will then save this order to the backend. I have another page called Saved orders that renders all these saved orders in separate rows in a table with a "Edit" button next to each one. When you click "Edit" it should redirect you to the Create Order page, but instead of being empty, it should be populated with all the information for that order. So if you want you can add more items, change quantity, etc.. How would I do this? I am looking for a conceptual answer.
So here is the idea, we don't pass lots of data via routes or even props etc. What we can do here is use the unique id or any other property and based on that we'll get our data and use it. There can be multiple ways to do this, I'll give you 2:
Little setup
Make a route for Edit which takes id as a param, so that for each edit we have a dynamic route, something like this:
<Route exact path="/order/edit/:id component={CreateOrder} />
(assuming CreateOrder is the name of the destined component).
Now your edit button should redirect to the relevant route upon click. For Class based component, you will have your button something like this:
<button onClick={()=>this.props.history.push(`/order/edit/${id}`)} />
and on CreateOrder Component, get the value of id param in componentDidMount (class based) or useEffect hook (function based).
for class based, you'll use this.props.match.params.id
for function based, you can use useParams() hook, like
let {id} = useParams()
As you are using same component for Creating and Editing, so apply a check on the basis of id, so if id is not null, treat your component as Edit otherwise Create.
if Edit, then either
Make an API Call
use your id to make a get request which will get all the fields for that particular order, and then set it into your State,
OR
Use Browser Storage
use browser localStorage or any state management tool like Redux, MobX etc and instead of calling an API get data for that particular id by using Array.find()
Based on your needs you can pick any option.

Integrate mui-datatable with admin-on-rest

How to integrate mui-datatable with admin-on-rest?
Need the following options in the list view :
move around ordering of columns
show/hide columns
change the number of rows for display
print preview of table
Mui-datatable has these features. According to admin-on-rest documentation, we can use custom Datagrid. Can anyone explain how to do it?
Say you are making a custom-datagrid component 'MyIterator'. This component has to just make use two props that will 'auto-magically' be available to the child of 'List' component. One prop is ids and another is data.
The ids prop is an array of id of currently displayable data-items. And the data is an object containing the data for all the items displayable.
Something like this should do the part of making a custom-datagrid -
const MyIterator = ({ids, data}) => ids.map(id=><div key={id}><span>Label</span><span>{data[id].label}</span></div>)
Above example presumed the data-item object to have a property of 'label'.
And this is how a custom-datagrid can be made.

Accessing a property from an array of objects stored in state in React

I'm working with ReactJS on a project and using KnexJS to access a database. I would like to store and use the JSON objects I retrieve, in the state of a component as something along the lines of the following.
this.setState({tutors: tutors}) //Retrieval from database after promise
and then access their properties like so
this.state.tutors[0].email
this.state.tutors[0].firstname
However, when I try this, I get the following error
TypeError: Cannot read property 'email' of undefined
I have checked the console.log as well as using JSON.stringify to determine if the objects are retrieved by the time I need them. And it appears that they are. I simply cannot access their properties from state.
Is there something I can do about this? Or do I need to retrieve them from the DB one by one?
This could be happening, because at the moment your code tries to retrieve data from state, the data is not there yet -- though it's possibly added later. This is something that happens quite often, in my experience. You should probably check that an object exists, before trying to access a property on it -- and return null or undefined in case it doesn't exist:
this.state.tutors[0] ? this.state.tutors[0].email : null
EDIT (in response to the additional code samples):
Assuming your fetch function works ok and adds the fetched data to state (I would use forEach instead of map to push the elements into the array, or just map over the fetched array and add that to the state directly, without an intermediary array/variable/push -- but I think your code should work)...
The problem has to do with the render method, since when the component renders initially the data is not yet in state, and as such you're passing an empty array to the TutorTable component, which probably in turn produces the error you see.
The data gets added to state later, but at this stage the error on the initial render has already happened.
You could solve this by rendering the TutorTable conditionally, only when the data gets added to the state:
<div className="col-7">
<h3> My Tutors </h3>
{this.state.tutors.length > 0 && <TutorsTable tutors={this.state.tutors} />}
</div>
if you console.log out this.state.tutors in the render() method you should see in the console an empty array ([]) returned on the initial render, and then an array filled with data when the component re-renders when the data is added to the state.
I hope this helps.
It appears to me you are trying to get the first element of an array this.state.tutors[0].email
is the tutors really an array,could provide the format of the data that you console logged as you stated.This probably should be in the comment section but I have less than 50 rep so i cant comment.
you should check first tutors. if you are getting tutors an array then you can access its first element.
if(this.state.tutors[0]) {
console.log("first element of tutors array", this.state.tutors[0].email)
// anything you can acccess now of this element
}
and assign first tutors as an empty array in state.
state = {
tutors: []
}
in first lifecycle you have no data in this.state.tutors[0]
for this reason first check this.state.tutors[0] is ready or not like this
if(this.state.tutors[0])
{
var data=this.state.tutors[0];
data.push('your data');
this.setState({tutors:data})
}

Resources