Columns from backend(API ) not working for useState - reactjs

I am fetching data from backend for Drag and Drop
const [productsList, setProductsList] = useState([]);
const loadData=async() =>
{
const response=await fetch("http://localhost:8000/api/getcandidates/");
const data=await response.json();
// console.log(data);
const savedate=data.candidate;
var myObject = JSON.parse(savedate);
setProductsList(myObject);
};
useEffect(() => {
loadData();
},[]);
So I got respond as
const items2FromBackend = [
{ id: 1, content: "First task", title: "JAVA DEVELOPER2", name:"shanu", status: "Inprogress", Skill: "HTML, CSS, JavaScript" , view: "", exp: "4.6Yrs", ctc: " 5LK/A", exctc: " 5LK/A", location: "kakkand", np: "2 Mth" },
{ id: 2, content: "First task", title: "JAVA DEVELOPER", name:"shanu", status: "Inprogress", Skill: "HTML, CSS, JavaScript" , view: "", exp: "4.6Yrs", ctc: " 5LK/A", exctc: " 5LK/A", location: "kakkand", np: "2 Mth"},
{ id: 3, content: "First task", title: "JAVA DEVELOPER2", name:"shanu", status: "Inprogress", Skill: "HTML, CSS, JavaScript" , view: "", exp: "4.6Yrs", ctc: " 5LK/A", exctc: " 5LK/A", location: "kakkand", np: "2 Mth"},
{ id: 4, content: "First task", title: "JAVA DEVELOPER", name:"shanu", status: "Inprogress", Skill: "HTML, CSS, JavaScript" , view: "", exp: "4.6Yrs", ctc: " 5LK/A", exctc: " 5LK/A", location: "kakkand", np: "2 Mth" },
{ id: 5, content: "First task", title: "JAVA DEVELOPER", name:"shanu", status: "Inprogress", Skill: "HTML, CSS, JavaScript" , view: "", exp: "4.6Yrs", ctc: " 5LK/A", exctc: " 5LK/A", location: "kakkand", np: "2 Mth" }
];
and this for drag and drop uuid
const columnsFromBackend = {
[uuid()]: {
name: "Inprogress",
items: productsList
},
[uuid()]: {
name: "Schedule",
items: []
},
[uuid()]: {
name: "Rejection",
items: []
},
[uuid()]: {
name: "Waiting",
items: []
}
};
const [columns, setColumns] = useState(columnsFromBackend);
useState(columnsFromBackend) is not working for back end fetch data productsList.But its working for hardcore data. Any help would be appreciated. Thanks in advance

Since you still need to await for the columnsFromBackend you need to use the setter instead of making it as a "default value". If you call useState(defaultValue). the parameter inside is the defaultValue and it will only be set once.
so in your case what you can do isv put it inside a useState:
const [columns, setColumns] = useState([]);
useState(() => {
setColumns(columnsFromBackend);
}, [columnsFromBackend])
So every time there is a change from columnsFromBackend it will update your state.

Related

How to pass in the initial state of the component

I have a React component and I want to test it with React Testing Library. The component has an initial state but I want to override it for my tests and provide a custom initial state so I can test various things. How to I do that in Jest?
function App() {
const initialState = [
{
id: uuidv4(),
date: new Date(),
desc: "initial",
amount: 0,
type: "travel",
},
];
const [expenses, setExpenses] = useState(initialState);
return (
<div className={Styles.app}>
<h1 className="p-4">Expense tracker</h1>
<Container>
<AddExpense setExpenses={setExpenses} expenses={expenses} />
<FilterExpense expenses={expenses} setExpenses={setExpenses} />
<ListExpense setExpenses={setExpenses} expenses={expenses} />
<BreakdownExpense expenses={expenses} />
</Container>
</div>
);
}
I tried the following but it's not working:
test("custom initial state", () => {
const initialState = [
{
id: 1,
date: new Date(),
desc: "test 1",
amount: 0,
type: "10",
},
{
id: 2,
date: new Date(),
desc: "test 2",
amount: 0,
type: "20",
},
{
id: 3,
date: new Date(),
desc: "test 3",
amount: 0,
type: "30",
},
];
const [expenses, setExpenses] = React.useState(initialState);
render(<App expenses={expenses} />);
expect(screen.getByText(/test 1/i)).toBeInTheDocument();
expect(screen.getByText(/test 2/i)).toBeInTheDocument();
});
--- Update
I have a fix for it but I don't like the implementation. I'm putting testing data and logic in the component but I should be keeping them separate.
App comp:
function App({ testApp }) {
const testInitialState = [
{
id: 1,
date: new Date(),
desc: "test 1",
amount: 0,
type: "10",
},
{
id: 2,
date: new Date(),
desc: "test 2",
amount: 0,
type: "20",
},
{
id: 3,
date: new Date(),
desc: "test 3",
amount: 0,
type: "30",
},
];
const initialState = [
{
id: uuidv4(),
date: new Date(),
desc: "initial",
amount: 0,
type: "initial",
},
];
const [expenses, setExpenses] = useState(
testApp ? testInitialState : initialState
);
return (......
test.js:
test(("filter expenses buttons", () => {
render(<App testApp={true} />);
expect(screen.getByText(/test 1/i)).toBeInTheDocument();
expect(screen.getByText(/test 2/i)).toBeInTheDocument();
});

Is there a way to group columns in MUI-dataTable?

I am using MUIDataTable in my React project. I just want to group columns by adding borders to the table. Please find the code below which I am using.
const columns = [
{
name: "name",
label: "Name",
options: {
filter: true,
sort: true,
[customBodyRender: (value) => {
return (
<div style={{ borderRight: "solid 2px" }} >
{value}
</div>
)
}][1]
}
},
{
name: "company",
label: "Company",
options: {
filter: true,
sort: false,
}
},
{
name: "city",
label: "City",
options: {
filter: true,
sort: false,
customBodyRender: (value) => {
return (
<div style={{ borderRight: "solid 2px" }} >
{value}
</div>
)
}
}
},
{
name: "state",
label: "State",
options: {
filter: true,
sort: false,
}
},
];
const data = [
{ name: "Joe James", company: "Test Corp", city: "Yonkers", state: "NY" },
{ name: "John Walsh", company: "Test Corp", city: "Hartford", state: "CT" },
{ name: "Bob Herm", company: "Test Corp", city: "Tampa", state: "FL" },
{ name: "James Houston", company: "Test Corp", city: "Dallas", state: "TX" },
{ name: "", company: "", city: "Tampa", state: "" },
{ name: "", company: "", city: "", state: "" },
{ name: "", company: "", city: "Hartford", state: "" },
{ name: "", company: "", city: "", state: "" },
{ name: "", company: "", city: "", state: "" },
{ name: "", company: "", city: "", state: "" },
];
const options = {
filterType: 'checkbox',
};
<MUIDataTable
title={"Employee List"}
data={data}
columns={columns}
options={options}
/>
This is not working as expected. Either the border height is not proper or in case of no data in the table row, there is no border at all.
I also want the borders to appear on the table headers.
I have attached the snapshot of the output for reference.
OutputImage
Is there a way to fix this?
there is a PR but it's in beta only https://github.com/gregnb/mui-datatables/pull/1441, not yet merged into the master branch

TypeError: posts is not iterable returning data from firebase

I'm new using react and firebase.
I try to get posts from firebase:
useEffect(() => {
setLoading(true);
setError(false);
let cancel;
// get posts
var postsRef = firebase.database().ref('/posts/');
postsRef.on('value', function(snapshot) {
setPosts(prevPosts => {
var posts = snapshot.val();
console.log(posts);
return [...prevPosts,...posts]
});
});
setLoading(false);
}, [ pageNumber ]);
The problem is it gives me:
TypeError: posts is not iterable on return [...prevPosts,...posts]
any ideas how to solve this? this will return data to a function that will parse data like this:
return (
<>
{posts.map((post, index) => {
return <Post key={post.id} id={post.id} ref={ref} img={post.img} titulo={post.titulo} />
})}
</>
)
Why I get this error? how can I parse my data correctly?
thanks!
Since your post variable is an object like:
{
"-M5GmoelPzWryNizVjww": { img: "img/", titulo: "title 1", user: "root" },
"-M5GmsTDcbDYZuoYBVIt": { img: "img/", titulo: "title 2", user: "root" },
"-M5GmxMZMzZe9p5uDuWe": { img: "img/", titulo: "title 3", user: "root" },
"-M5GmyKDbbtxR8Dw3-J2": { img: "img/", titulo: "title 4", user: "root" },
"-M5GmzHjK1PQJ2ulrCTi": { img: "img/", titulo: "title 5", user: "root" },
"-M5Gn2Rsv_OrwL1GkbVG": { img: "img/", titulo: "title 6", user: "user" },
"-M5Gn39y9JDishOdxwi4": { img: "img/", titulo: "title 7", user: "user" }
}
You should transform it previously to an array so that you can concatenate it to your previous list of posts. To do so, and using the key of the object as an id, you can use:
return [...prevPosts, ...Object.keys(posts).map(key => ({
id: key,
...posts[key]
}))];

Issue while using react-picky select menu

I have recently downloaded the react-picky and have used it inside a map function to loop through my dynamic data. In the picky i have set multiselect as true.
How ever on the onchange function am getting only the currently selected value and not the list of values selected for picky.
The issue am facing is in the case of multiselect where the value will be a single object containing the current selected item rather than the list of items selected. Could you please help me with the issue. I have tried every possible solution and it does not seem to work.Any help would be really appreciated as am stuck in the issue for sometime.
const sectorsData = [
{
name: "Technology",
options: [
{
id: "1",
name: "AI & Analytics"
},
{
id: "2",
name: "Robotics"
},
{
id: "3",
name: "IoT"
}
]
},
{
name: "Sector",
options: [
{
id: "1",
name: "Automotive"
},
{
id: "2",
name: "Oil and gas"
},
{
id: "3",
name: "Consumer Products"
}
]
},
{
name: "Accounts",
options: [
{
id: "1",
name: "Alphabet Inc."
},
{
id: "2",
name: "General Motors Company"
},
{
id: "3",
name: "Consumer Products"
},
{
id: "4",
name: "State Street Corporation"
}
]
},
{
name: "Region",
options: [
{
id: "1",
name: "Canada Region"
},
{
id: "2",
name: "Central"
},
{
id: "3",
name: "FSO Americas"
},
{
id: "4",
name: "Latam North"
},
{
id: "5",
name: "Latam South"
}
]
}
];
const App = props => {
const [assetsAddedState, setAssetsAddedState] = React.useState({
selectedItems: []
});
const selectedOption = (name, value) => {
setAssetsAddedState(prev => {
return { ...prev, [name]: value };
});
};
return (
<form className="create-work-form-container" noValidate autoComplete="off">
{sectorsData.map((selectItem, i) => (
<Picky
value={assetsAddedState[selectItem.name]}
onChange={selectedOption.bind(this, selectItem.name)}
options={selectItem.options}
placeholder={selectItem.name}
numberDisplayed={1}
valueKey="id"
labelKey="name"
multiple={true}
includeSelectAll={true}
includeFilter={true}
dropdownHeight={600}
className="multiSelectControl "
name={selectItem.name}
/>
))}
</form>
);
};
value should be returning the multiple values user has selected.
See if this is working for you:
Working example on CodeSandbox:
https://codesandbox.io/s/react-pickyanswerso-yp02j
import React from "react";
import { render } from "react-dom";
import Picky from "react-picky";
import "react-picky/dist/picky.css";
const sector1 = {
name: "Technology",
options: [
{
id: "1",
name: "AI & Analytics"
},
{
id: "2",
name: "Robotics"
},
{
id: "3",
name: "IoT"
}
]
};
const sector2 = {
name: "Sector",
options: [
{
id: "4",
name: "Automotive"
},
{
id: "5",
name: "Oil and gas"
},
{
id: "6",
name: "Consumer Products"
}
]
};
const sector3 = {
name: "Accounts",
options: [
{
id: "7",
name: "Alphabet Inc."
},
{
id: "8",
name: "General Motors Company"
},
{
id: "9",
name: "Consumer Products"
},
{
id: "10",
name: "State Street Corporation"
}
]
};
const sector4 = {
name: "Region",
options: [
{
id: "11",
name: "Canada Region"
},
{
id: "12",
name: "Central"
},
{
id: "13",
name: "FSO Americas"
},
{
id: "14",
name: "Latam North"
},
{
id: "15",
name: "Latam South"
}
]
};
const App = props => {
// const [assetsAddedState, setAssetsAddedState] = React.useState([]);
const [selected1, setSelected1] = React.useState([]);
const [selected2, setSelected2] = React.useState([]);
const [selected3, setSelected3] = React.useState([]);
const [selected4, setSelected4] = React.useState([]);
const selectedOption1 = value => {
console.log("VAlue: " + JSON.stringify(value));
setSelected1(value);
};
const selectedOption2 = value => {
console.log("VAlue: " + JSON.stringify(value));
setSelected2(value);
};
const selectedOption3 = value => {
console.log("VAlue: " + JSON.stringify(value));
setSelected3(value);
};
const selectedOption4 = value => {
console.log("VAlue: " + JSON.stringify(value));
setSelected4(value);
};
return (
<form className="create-work-form-container" noValidate autoComplete="off">
<Picky
value={selected1}
onChange={selectedOption1}
options={sector1.options}
placeholder={sector1.name}
numberDisplayed={1}
valueKey="id"
labelKey="name"
multiple={true}
includeSelectAll={true}
includeFilter={true}
dropdownHeight={600}
className="multiSelectControl "
name={sector1.name}
/>
<Picky
value={selected2}
onChange={selectedOption2}
options={sector2.options}
placeholder={sector2.name}
numberDisplayed={1}
valueKey="id"
labelKey="name"
multiple={true}
includeSelectAll={true}
includeFilter={true}
dropdownHeight={600}
className="multiSelectControl "
name={sector2.name}
/>
<Picky
value={selected3}
onChange={selectedOption3}
options={sector3.options}
placeholder={sector3.name}
numberDisplayed={1}
valueKey="id"
labelKey="name"
multiple={true}
includeSelectAll={true}
includeFilter={true}
dropdownHeight={600}
className="multiSelectControl "
name={sector3.name}
/>
<Picky
value={selected4}
onChange={selectedOption4}
options={sector4.options}
placeholder={sector4.name}
numberDisplayed={1}
valueKey="id"
labelKey="name"
multiple={true}
includeSelectAll={true}
includeFilter={true}
dropdownHeight={600}
className="multiSelectControl "
name={sector4.name}
/>
</form>
);
};
render(<App />, document.getElementById("root"));

TypeError: _SchoolProduct__WEBPACK_IMPORTED_MODULE_2___default.a.map is not a function

I am new at ReactJs and try to complete a task from the youtube channel.
I created array "products" in "SchoolProduct.js" then using props I passed the value in Product.js.
Now in App.js, I used map function to get data
(Maybe I understand something wrong about props or map function)
Here is SchoolProduct.js:
const products = [
{
id: "1",
name: "pencil",
price: 1,
description: "this is pencil"
},
{
id: "2",
name: "rubber",
price: 10,
description: "this is rubber"
}
]
this is my Product.js
import React from "react"
function Product(props)
{
return
(
<div>
<h2>{props.product.name}</h2>
<p>{props.product.price.toLocaleString("en-US", {style: "currency",
currency: "USD"})}
- {props.product.description}</p>
</div>
)
}
export default Product
and this my App.js
import React, { Component } from 'react';
import Product from "./Product"
import productsData from "./SchoolProduct"
function App(){
const productsComponents = productsData.map(item => <Product product=
{item}/>)
return (
<div>
{productsComponents}
</div>
)
}
export default App;
The Error is:
TypeError: _SchoolProduct__WEBPACK_IMPORTED_MODULE_2___default.a.map is not a function
its shows error in App.js line no 8, which is "const productsComponents"
I know I create a silly mistake, but I am trying to improve it
I have to export my error in default way,
const products = [
{
id: "1",
name: "pencil",
price: 1,
description: "this is pencil"
},
{
id: "2",
name: "rubber",
price: 10,
description: "this is rubber"
}
]
export default products
export default [
{
id: "1",
name: "Pencil",
price: 1,
description: "Perfect for those who can't remember things! 5/5 Highly recommend."
},
{
id: "2",
name: "Housing",
price: 0,
description: "Housing provided for out-of-state students or those who can't commute"
},
{
id: "3",
name: "Computer Rental",
price: 300,
description: "Don't have a computer? No problem!"
},
{
id: "4",
name: "Coffee",
price: 2,
description: "Wake up!"
},
{
id: "5",
name: "Snacks",
price: 0,
description: "Free snacks!"
},
{
id: "6",
name: "Rubber Duckies",
price: 3.50,
description: "To help you solve your hardest coding problems."
},
{
id: "7",
name: "Fidget Spinner",
price: 21.99,
description: "Because we like to pretend we're in high school."
},
{
id: "8",
name: "Sticker Set",
price: 14.99,
description: "To prove to other devs you know a lot."
}
]

Resources