Can't use wrapped fetch component in my .jsx - reactjs

I have a MainComponentWrapper that is a fetch Get:
export default function MainComponentWrapper({ url, children }) {
const classes = useStyles()
const [data, setData] = React.useState()
React.useEffect(() => {
fetch(url, {
method: "GET",
headers: {
"Content-Type": "application/json",
Authorization: "Bearer " + window.localStorage.getItem("access_token"),
},
})
.then(resp => {
return resp.json()
})
.then(fetchedData => {
setData(fetchedData)
})
.catch(error => {
console.log(error)
window.localStorage.removeItem("access_token")
window.location.replace("/")
})
}, [url])
if (data === undefined) {
return (
<div className={classes.root}>
<CircularProgress className={classes.progress} />
</div>
)
}
return (
<div className={classes.root}>
{React.cloneElement(children, { data: data })}
</div>
)
}
I was trying to use it in my .jsx component so i could get data that i need by passing an api url, and print it on a table.
export default function Machines({data}) {
return (
<div className={classes.root}>
<h1>Azure machines</h1>
<Table className={classes.table} size="small">
<TableHead>
<TableRow>
<TableCell align="left">name</TableCell>
<TableCell align="left">resource_group</TableCell>
<TableCell align="left">location</TableCell>
<TableCell align="left">status</TableCell>
</TableRow>
</TableHead>
<TableBody>
{data.map(row => (
<TableRow key={row.name + row.resource_group}>
<TableCell align="left" component="th" scope="row">
<StyledButton size = "small" className={style.size3}>
<Link style={{ color: 'inherit', textDecoration: 'inherit'}} to={`/machines/${row.resource_group + "/" + row.name}`}>{row.name}</Link>
</StyledButton>
</TableCell>
<TableCell align="left">{row.resource_group}</TableCell>
<TableCell align="left">{row.location}</TableCell>
<MainComponentWrapper url={"/api/machine/one"} >
{({ tmpData }) => (
<TableCell key= {row.location + row.name} log={console.log(data.status)} align="left">
<LoadingIndicator/>
<MachineStatusIcon
status_code={tmpData.status_code}
status={tmpData.status}
/>
</TableCell>
)}
</MainComponentWrapper>
</TableRow>
))}
</TableBody>
</Table>
</div>
)
}
The problem is I can't find a way to use it, I've checked some similar examples but no success.
If i inspect on google chrome and check the network tab i can see that the component is fetching the data, because the data is listed there, but how do i use it to pass as values to my table?

Your MainComponentWrapper is inside where you have 'data' defined. Your wrapper should envelope the entire JSX code which in this case is the table.
<MainComponentWrapper url={"/api/machine/one"} >
<TableBody>
<!-- data is being used here but it didn't exist -->
{data.map(row => (
<TableRow key={row.name + row.resource_group}>
<TableCell align="left" component="th" scope="row">
<StyledButton size = "small" className={style.size3}>
<Link style={{ color: 'inherit', textDecoration: 'inherit'}} to={`/machines/${row.resource_group + "/" + row.name}`}>{row.name}</Link>
</StyledButton>
</TableCell>
<TableCell align="left">{row.resource_group}</TableCell>
<TableCell align="left">{row.location}</TableCell>
{({ tmpData }) => (
<TableCell key= {row.location + row.name} log={console.log(data.status)} align="left">
<LoadingIndicator/>
<MachineStatusIcon
status_code={tmpData.status_code}
status={tmpData.status}
/>
</TableCell>
)}
</TableRow>
))}
</TableBody>
</MainComponentWrapper>

Related

My useEffect is not working. It is not getting called

I tried to get the users data through a useEffect and useEffect is not getting called. This is my allUsers.js file. Backend API is working and the UserService file is also working fine. I am only getting the first console log printed as mg. other console logs are not being printed.
export default function ViewUsers() {
const [userList, setUserList] = useState('');
console.log(userList,"mg")
useEffect(() => {
handleUser()
console.log("sas")
}, [])
const handleUser = async () =>{
const users = await UserService.viewUser()
setUserList(users);
console.log(userList,"user")
}
console.log(userList ,"1gmg")
return (
<>
<TableContainer component={Paper}>
<Table sx={{ minWidth: 650 }} aria-label="simple table">
<TableHead>
<TableRow>
<TableCell>Name</TableCell>
<TableCell align="right">Email</TableCell>
<TableCell align="right">Birth date</TableCell>
</TableRow>
</TableHead>
<TableBody>
{userList.map((row) => (
<TableRow
key={row.id}
sx={{ '&:last-child td, &:last-child th': { border: 0 } }}
>
<TableCell component="th" scope="row">
{row.name}
</TableCell>
<TableCell align="right">{row.email}</TableCell>
<TableCell align="right">{row.birthDate}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
</>
)
}

reactjs conditional statement inside TableCell

How do I input conditional if else statement in a TableCell for ReactJS. I want the data table to output nothing is found if the search box returns nothing.
Here is the code:
export default function DataTable () {
const [query, setQuery] = useState('')
const [tableData, setTableData] = useState([])
useEffect( function () {
const fetchUsers = async function () {
const response = await axios.get(`/search/?query=${query}`)
setTableData(response.data)
}
if (query.length === 0 || query.length > 2) fetchUsers()
}, [query])
return (
<>
<input type={'text'} placeholder={'Enter Teacher ID Number....'} className='search-bar' onChange={(event) => setQuery(event.target.value)} />
<TableContainer component={Paper} className='data-table'>
<Table sx={{minWidth: 650}} aria-label='simple table'>
<TableHead>
<TableRow>
<TableCell className='tableCell'>ID</TableCell>
<TableCell className='tableCell'>Name</TableCell>
<TableCell className='tableCell'>Surname</TableCell>
<TableCell className='tableCell'>Title</TableCell>
<TableCell className='tableCell'>Email</TableCell>
<TableCell className='tableCell'>Action #1</TableCell>
<TableCell className='tableCell'>Action #2</TableCell>
</TableRow>
</TableHead>
<TableBody>
{ tableData.map((data) => (
<TableRow key={data.id} sx={{ '&:last-child td, &:last-child th': {border:0}}}>
<TableCell className='tableCell'> { data.id }</TableCell>
<TableCell className='tableCell'> { data.name }</TableCell>
<TableCell className='tableCell'> { data.surname }</TableCell>
<TableCell className='tableCell'> { data.title }</TableCell>
<TableCell className='tableCell'> { data.email}</TableCell>
<TableCell className='tableCell'>
<button className={'verify'}>
<Link to={`/search/${data.id}`} className={'verify'} state={data}>Verify</Link>
</button>
</TableCell>
<TableCell className='tableCell'>
<button className={`drop`}>
<Link to={`/drop/${data.id}`} className={'drop'} state={data}>Drop</Link>
</button>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
</>
)
}
I tried to input ternary operator '?' but it returns the first result
First of all I recommend to you separate the mapped Row in a separated component to handle easily and get the code more readable. This component could be in other file.
On the other hand I highly recommend if you are consuming the data from rest service, is using React Query.
export default function DataTable () {
const [query, setQuery] = useState('')
const [tableData, setTableData] = useState([])
useEffect( function () {
const fetchUsers = async function () {
const response = await axios.get(`/search/?query=${query}`)
setTableData(response.data)
}
if (query.length === 0 || query.length > 2) fetchUsers()
}, [query])
function UserTableRow(user){
return (
<TableRow key={user.id} sx={{ '&:last-child td, &:last-child th': {border:0}}}>
<TableCell className='tableCell'> { user.id }</TableCell>
<TableCell className='tableCell'> { user.name }</TableCell>
<TableCell className='tableCell'> { user.surname }</TableCell>
<TableCell className='tableCell'> { user.title }</TableCell>
<TableCell className='tableCell'> { user.email}</TableCell>
<TableCell className='tableCell'>
<button className={'verify'}>
<Link to={`/search/${user.id}`} className={'verify'} state={data}>Verify</Link>
</button>
</TableCell>
<TableCell className='tableCell'>
<button className={`drop`}>
<Link to={`/drop/${user.id}`} className={'drop'} state={data}>Drop</Link>
</button>
</TableCell>
</TableRow>
)
}
return (
<>
<input type={'text'} placeholder={'Enter Teacher ID Number....'} className='search-bar' onChange={(event) => setQuery(event.target.value)} />
<TableContainer component={Paper} className='data-table'>
<Table sx={{minWidth: 650}} aria-label='simple table'>
<TableHead>
<TableRow>
<TableCell className='tableCell'>ID</TableCell>
<TableCell className='tableCell'>Name</TableCell>
<TableCell className='tableCell'>Surname</TableCell>
<TableCell className='tableCell'>Title</TableCell>
<TableCell className='tableCell'>Email</TableCell>
<TableCell className='tableCell'>Action #1</TableCell>
<TableCell className='tableCell'>Action #2</TableCell>
</TableRow>
</TableHead>
<TableBody>
{ tableData?.map((user) => <UserTableRow user={user}/>)}
{!tableData.length && <div>No results found.</div>}
</TableBody>
</Table>
</TableContainer>
</>
)
}

React - How to break a line in a cell of a material ui table

I'm using the DenseTable component of the ui material and wanted to break a string into parts
here is my table:
I want in the cursos column, in the line that has LEIT - 1st Ano/LEE - 1st Ano I want to break the string where there is the '/'
below my DenseTable component code:
function createData(aulaID, numAula, tipoAula, nome, curso, data, acao) {
return { aulaID, numAula, tipoAula, nome, curso, data, acao };
}
export default function DenseTable() {
const { selectedRow, setSelectedRow, cursoSigla } = useListarAulas();
const [rows, setRows] = React.useState([]);
const {
showLancarSumarioModal,
handleOpenLancarSumarioModal,
handleCloseLancarSumarioModal,
} = useEscreverSumario();
const {
aulas,
// docente,
} = useFiltrarAulas();
React.useEffect(() => {
if (rows.length !== aulas.length) {
const tempRows = [];
aulas.map((aula) =>
tempRows.push(
createData(
aula.id,
aula.numero,
aula.tipo,
aula.disciplina.codigo,
cursoSigla(aula.cursos),
aula.data,
'Lançar Sumario'
)
)
);
setRows(tempRows);
}
}, [aulas, rows]);
return (
<>
<TableContainer component={Paper}>
<Table sx={{ minWidth: 650 }} size="small" aria-label="a dense table">
<TableHead>
<TableRow>
<TableCell>Disciplina</TableCell>
<TableCell align="right">Curso</TableCell>
<TableCell align="right">Data</TableCell>
<TableCell align="right">Acção</TableCell>
</TableRow>
</TableHead>
<TableBody>
{rows.map((row) => (
<TableRow
key={row.nome}
sx={{ '&:last-child td, &:last-child th': { border: 0 } }}
>
<TableCell component="th" scope="row">
{row.nome}
</TableCell>
<TableCell align="right">{row.curso}</TableCell>
<TableCell align="right">
{row.data}
{/* moment(row.data).format('yyyy-MM-DD') */}
</TableCell>
<TableCell align="right">
<Button
size="small"
onClick={() => {
setSelectedRow(row);
handleOpenLancarSumarioModal();
}}
>
{row.acao}
</Button>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
<EscreverSumarioModal
showModal={showLancarSumarioModal}
handleCloseModal={handleCloseLancarSumarioModal}
selectedRow={selectedRow}
/>
</>
);
}
the function cursoSigla() in useEffect receives a courses object where their respective acronyms are and returns a string concatenated with the acronym of each course like this "LEIT - 1º Ano/LEE - 2º Ano"
below the function code:
function cursoSigla(cursos) {
const sigla = [];
if (cursos.length > 1) {
if (sigla.length !== cursos.length) {
cursos.map((curso) => sigla.push(`${curso.sigla} - ${curso.ano}º Ano`));
return sigla.join('/');
}
}
if (cursos.length === 1) {
sigla.push(cursos[0].sigla);
return `${sigla[0]} - ${cursos[0].ano}º Ano`;
}
console.log(sigla);
return '';
}
My question is how to introduce a line break in my table cell ?
Instead of rendering them as:
<TableCell align="right">{row.curso}</TableCell>
You could do something like this instead:
<TableCell>
{row.curso.split("/").map((curs, idx) => (
<p key={idx}>{curs}</p>
))}
</TableCell>

ComponentDidMount not firing in ReactJS

I have suddenly run into this problem in my app, the componentDidMount does not work when loading the page and I get typescript error due to the information not being loaded. It was working fine yesterday and the day before and now I have no idea what I did wrong. I have 4 api calls for the method GET, it's only for the GET method. Is there a way to make the component work again ? I have no idea why it behaves this way.
class adminView extends Component {
constructor(props) {
super(props);
this.state = {
Users: [],
Movies: [],
Comments: [],
Ratings: [],
message: null,
};
}
componentDidMount() {
this.reloadObjectiveList().then((r) => console.log("result" + r));
this.reloadUserList().then((r) => {
console.log("result" + r);
});
}
async reloadUserList() {
await UserApiService.fetchUsers().then((res) => {
console.log(res);
this.setState({
Users: res.data.result,
});
});
}
async reloadObjectiveList() {
await UserApiService.fetchUsers().then((res) => {
console.log(res);
this.setState({
Users: res.data.result,
});
});
await MovieApiService.fetchMovies().then((res) => {
this.setState({
Movies: res.data.result,
});
});
await CommentApiService.fetchComments().then((res) => {
console.log(res.data.result);
this.setState({
Comments: res.data.result,
});
});
await RatingApiService.fetchrating().then((res) => {
console.log(res.data.result);
this.setState({
Ratings: res.data.result,
});
});
}
deleteUsersComments(ObjectiveId) {
CommentApiService.deleteComment(ObjectiveId).then((res) => {
this.setState({ message: "Objective deleted successfully." });
this.setState({
Comments: this.state.Comments.filter(
(Objective) => Objective.username !== ObjectiveId
),
});
});
}
deleteUsersRatingss(ObjectiveId) {
RatingApiService.deleterating(ObjectiveId).then((res) => {
this.setState({ message: "Objective deleted successfully." });
this.setState({
Ratings: this.state.Ratings.filter(
(Objective) => Objective.username !== ObjectiveId
),
});
});
}
deleteMovies(ObjectiveId) {
MovieApiService.deleteTourist(ObjectiveId).then((res) => {
this.setState({ message: "Objective deleted successfully." });
this.setState({
Movies: this.state.Movies.filter(
(Objective) => Objective.imdb_id !== ObjectiveId
),
});
});
}
deleteUsers(ObjectiveId) {
UserApiService.deleteTourist(ObjectiveId).then((res) => {
this.setState({ message: "Objective deleted successfully." });
this.setState({
Movies: this.state.Movies.filter(
(Objective) => Objective.username !== ObjectiveId
),
});
});
}
render() {
const { details, loading } = this.props;
return (
<main className={styles.main}>
<Paper className={styles.paper}>
<Typography component="h1" variant="h5">
Hello ADMIN
</Typography>
<hr />
<Typography component="h1" variant="h5">
Users:
</Typography>
<div className="card-list">
{console.log(this.state.Users)}
{this.state.Users.map((item) => (
<CardUsers item={item} key={item.username} />
))}
</div>
<Table>
<TableHead>
<TableRow>
<TableCell>UserFirstName</TableCell>
<TableCell>UserLastName</TableCell>
<TableCell>UserEmail</TableCell>
</TableRow>
</TableHead>
<TableBody>
{this.state.Users.map((row) => (
<TableRow key={row.username}>
<TableCell align="center">{row.firstName}</TableCell>
<TableCell align="center">{row.lastName}</TableCell>
<TableCell align="center">{row.email}</TableCell>
<TableCell
align="center"
onClick={() => this.deleteUsers(row.username)}
>
<DeleteIcon />
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
<hr />
<Typography component="h1" variant="h5">
MOVIES
</Typography>
<hr />
<div className="card-list">
<Card item={this.state.Movies} />
</div>
<Typography component="h1" variant="h5">
Comments
</Typography>
<hr />
<hr />
<Table>
<TableHead>
<TableRow>
<TableCell>UserId</TableCell>
<TableCell>Comment</TableCell>
</TableRow>
</TableHead>
<TableBody>
{this.state.Comments.map((row) => (
<TableRow key={row.username}>
<TableCell align="center">{row.username}</TableCell>
<TableHead>
<TableCell>MovieID</TableCell>
<TableCell>Comment</TableCell>
</TableHead>
<TableBody>
{row.commentsList.map((row2) => (
<TableRow key={row2.id}>
<TableCell align="center">{row2.movieID}</TableCell>
<TableCell align="center">{row2.comment}</TableCell>
<TableCell
align="center"
onClick={() => this.deleteUsersComments(row2)}
>
<DeleteIcon />
</TableCell>
</TableRow>
))}
</TableBody>
</TableRow>
))}
</TableBody>
</Table>
<Typography component="h1" variant="h5">
Ratings
</Typography>
<hr />
<hr />
<Table>
<TableHead>
<TableRow>
<TableCell>UserId</TableCell>
<TableCell>Ratings</TableCell>
</TableRow>
</TableHead>
<TableBody>
{this.state.Ratings.map((row) => (
<TableRow key={row.username}>
<TableCell align="center">{row.username}</TableCell>
<TableHead>
<TableCell>MovieID</TableCell>
<TableCell>Rating</TableCell>
</TableHead>
<TableBody>
{row.ratingsList.map((row2) => (
<TableRow key={row2.id}>
<TableCell align="center">{row2.movieID}</TableCell>
<TableCell align="center">{row2.rating}</TableCell>
<TableCell
align="center"
onClick={() => this.deleteUsersRatingss(row2)}
>
<DeleteIcon />
</TableCell>
</TableRow>
))}
</TableBody>
</TableRow>
))}
</TableBody>
</Table>
</Paper>
</main>
);
}
}
export default withRouter(withStyles(styles)(adminView));

react-sortable-hoc stops after first move with edgeOffset

I'm attempting to make a sortable table with react-sortable-hoc. This works fine for the first move but afterwards, react-sortable-hoc will stop working. The row in the table no longer animates and attempting to move an item throws the following error:
TypeError: edgeOffset is undefined
This is the relevant code:
const DragHandle = SortableHandle(() => <DragIndicatorIcon />);
const SortableItem = SortableElement(({ value, sortIndex, groupType }) => {
return (
<TableRow
hover
key={value.id}
index={sortIndex}
>
<TableCell><DragHandle /></TableCell>
<TableCell component="th" scope="row">
{value.fullname}
</TableCell>
<TableCell numeric>{value.number}</TableCell>
{groupType &&
<TableCell>10</TableCell>
}
</TableRow>
);
});
const SortableList = SortableContainer(({ items, groupType }) => {
return (
<TableBody>
{items.map((user, index) => {
return (
<SortableItem key={`item-${index}`} groupType={groupType} index={index} sortIndex={index} value={user} />
);
})}
</TableBody>
);
});
And:
<Table className={classes.table}>
<TableHead>
<TableRow>
<TableCell />
<TableCell>Name</TableCell>
<TableCell numeric>Number</TableCell>
{this.props.groupType === "1" &&
<TableCell>Seconds</TableCell>
}
</TableRow>
</TableHead>
<SortableList items={this.props.items} groupType={this.props.groupType === "1"} onSortEnd={this.props.onSortEnd} useDragHandle={true} useWindowAsScrollContainer={true} />
</Table>

Resources