How to append multiple values in setstate for array object Reactjs - javascript

I want to append objects in my array using setState function.
My initial variable looks like this:
columns1: [
{
title: "Sr. No.",
render(text, record, index) {
return {
children: <div> {index + 1}</div>,
};
},
},
{
title: "Account ID",
dataIndex: "Accountid",
},
{
title: "Alias",
dataIndex: "Alias",
},
],
Now, in a function I want to add 2 more objects in columns1:
const projCol = {
title: "Projected Cost",
dataIndex: "forecast_amount",
key: "forecast_amount",
},
const projChange = {
title: "Percentage Change",
dataIndex: "%change",
key: "%change",
}
if I only wanted to add projCol I can do
this.setState((prevState) => {
return {
columns1: [...prevState.columns1,projCol],
};
});
but how can I add both projCol and projChange?

Just add one more element to the array like you do with projCol, separated by commas.
this.setState((prevState) => {
return {
columns1: [...prevState.columns1, projCol, projChange]
};
});

Related

Editing only the real DOM on ReactJS in order to present a formated number/string maintaining the real number

Hi i'm new to ReactJS and i'm using it with ReactDataGrid, and i can't understand how can i change only the real dom value of a cell.
I have the following table:
And i want to change the price, instead of "3000000000" to "300M".
I have the JS function to perform this, but i can't apply it to the directly to ReactObject otherwise i will not be able to sort or filter, so i think the only way would be to only edit the RealDOM.
Following the documentation on the ReactDataGrid, i can access the ReactNode by using renderRow. But i don't know how to change the real dom in order to display the formated number.
Code:
const columns = [
//{ name: 'shop_vid', header: 'shop_vid', minWidth: 1, defaultFlex: 2 },
{ name: 'name', header: 'Name', minWidth: 10, defaultFlex: 2 },
{ name: 'price', header: 'Price', minWidth: 10, defaultFlex: 2 },
]
const filterValue = [
{ name: 'name', operator: 'contains', type: 'string', value: '' },
{ name: 'price', operator: 'gte', type: 'number', value: 0 },
];
const gridStyle = { minHeight: 550 }
const renderRow = ({ data, style }) => {
const { price } = data
//formatNumber(price)
}
class ItemsTable extends Component {
render() {
return (
<ReactDataGrid
idProperty="shop_vid"
pagination
defaultFilterValue={filterValue}
columns={columns}
dataSource={this.state.items}
style={gridStyle}
renderRow={renderRow}
defaultLimit={10}
/>
);
}
}
export default ItemsTable;
Thanks in Advance.
After diging more i found a solution.
ReactDataGrid allows to apply a render function on the columns list. So i just changed the props of the price column.
const columns = [
{ name: 'name', header: 'Name', minWidth: 10, defaultFlex: 2 },
{
name: 'price',
header: 'Price',
minWidth: 10,
type: 'number',
defaultFlex: 2,
render: ({ value }) => {
return convertValue(value);
}
}
]
Where value is the value of the cell and "convertValue" returns the formated number.

GraphQL Datatable, how to access the field of a field

I have a query in GraphQL as follows:
person {
id
title {
name
}
}
I am having an issue to pass to the datatable component the name of the title as a reference.
I define the columns as follows, but as it is expected the title name doesn't display. Any idea on how to reference the title name?
const columns = [
{
name: "id",
label: "ID",
},
{
name: "title.name",
label: "Title Name",
}
]
I found the solution, one has to do as follows:
{
name: "title",
label: "Title",
options: {
customBodyRender: (dataIndex, tableMeta, updateValue) => {
return dataIndex.title;
}
}
},

Updating a specific object in an array

I'm writing an SPA in Svelte. Now, I'm fairly new to the concepts of ES6 so I'm having difficulties wrapping my head around some basic concepts.
I have a store:
import { writable } from "svelte/store";
function selectedOptions() {
const selection = writable([
{
id: 1,
title: "Title 1",
selections: []
},
{
id: 2,
title: "Title 2",
selections: []
},
{
id: 3,
title: "Title 3",
selections: []
},
{
id: 4,
title: "Title 4",
selections: []
},
{
id: 5,
title: "Title 5",
selections: []
},
{
id: 6,
title: "Title 6",
selections: []
}
]);
return {
subscribe: selection.subscribe,
updateSelection: item => {
selection.update((items) => {
//I want to update the object with the same id as the object
//I'm passing in to the method.
});
};
}
}
export default selectedOptions();
In my component, I want to pass an object and update the corresponding object in my array with provided values:
function handleChange(e) {
selectedOptions.updateSelection({
id: 1, title: "Title 1", selections: ["Option 1, Option 2"]
});
}
How do I "replace" an existing object with a new one thus triggering an update to all components that are subscribing to the store?
Use the spread syntax to copy all the original keys, then add the one you want to modify:
selection.update(items => {
return {
...items,
[item.id]: item
}
});
You could use the array method map and merge the new and old object if the id matches or just return the old object as-is if the id doesn't match.
updateSelection: item => {
selection.update(items => {
return items.map(i => (i.id === item.id ? { ...i, ...item } : i));
});
};

Moving React constant to its own file when it needs callbacks from a class

Currently I have created a component that wraps BootstrapTable. I have to define a constant that represents the columns of data. But, the way I have it right now seems to really clutter up my render method. I'd like to move it to its own file, but I'm not sure the best way to do this, because it requires callbacks that are defined in the class (notably the onUpdateClicked method).
If the way I have it is a fine way of doing things, that would be good to know. But, assuming I did want to move it to another file regardless, suggestions would be appreciated for my own edification. Thanks!
class MyTable extends Component {
onUpdateClicked() {
//do stuff
}
render() {
let {data} = {...this.props}
let columns = [
{
dataField: 'badge',
text: 'Badge',
sort: true
}, {
dataField: 'firstName',
text: 'First',
sort: true
}, {
dataField: 'lastName',
text: 'Last',
sort: true
}, {
dataField: 'email',
text: 'Email',
sort: true
}, {
dataField: 'loggedIn',
text: 'Logged In',
sort: true,
formatter: (cell, row) => {
if (row.loggedIn) {
return (<FontAwesomeIcon icon="check"/>)
}
}
}, {
dataField: 'update',
text: 'Update',
formatter: () => {
return (<Button onClick={this.onUpdateClicked} color="primary">Update</Button>)
}
},
];
return (
<div>
<BootstrapTable Bootstrap4 keyField='badge' data={data} columns={columns}/>
</div>
)
}
}
you can put the columns in a seperate file, but export a function that takes a function as a parameter to be used for the onClick
Columns.js
const columnsFn = someFunc => ([ // pass the function as a param.
{
dataField: 'badge',
text: 'Badge',
sort: true
}, {
dataField: 'firstName',
text: 'First',
sort: true
}, {
dataField: 'lastName',
text: 'Last',
sort: true
}, {
dataField: 'email',
text: 'Email',
sort: true
}, {
dataField: 'loggedIn',
text: 'Logged In',
sort: true,
formatter: (cell, row) => {
if (row.loggedIn) {
return (<FontAwesomeIcon icon="check"/>)
}
}
}, {
dataField: 'update',
text: 'Update',
formatter: () => {
return (<Button onClick={someFunc} color="primary">Update</Button>) // use it here
}
},
]);
export default columnsFn;
YourFile.js
import columnsFn from './columns';
class MyTable extends Component {
onUpdateClicked() {
//do stuff
}
render() {
const {data} = {...this.props}
const myColumns = columnsFn(this.onUpdateClicked); // pass the function here
return (
<div>
<BootstrapTable Bootstrap4 keyField='badge' data={data} columns={myColumns}/>
</div>
)
}
}

Javascript - How to return a partial array from a function?

I would like to insert in the middle of a columns array, many elements based on a parameter returned by the function getSpecificColumns(parameter).
The first one is working cause it is returning a single object, but is there any way to return many elements in the middle of the array?
$scope.getSpecificColumns = function (myParam) {
return { field: "SpecificField1", format: "{0:c}" };
}
$scope.getSpecificColumnsNotWorking = function (myParam) {
return { field: "SpecificField2", format: "{0:c}" },
{ field: "SpecificField3", format: "{0:c}" };
}
$scope.positionMontantNavGridOptions = {
height: 630,
filterable: {
mode: "row"
},
pageable: true,
columns: [
{ field: "Field1", width: "200px" },
{ field: "Field2", title: "Field 2", width: "80px" },
getSpecificColumns(parameter),
{ field: "Field4" }
]
}
If you want to return an array, return an array:
$scope.getSpecificColumnsNotWorking = function (myParam) {
return [{ field: "SpecificField2", format: "{0:c}" },
{ field: "SpecificField3", format: "{0:c}" }];
}
A expression such as:
{ field: "SpecificField2", format: "{0:c}" },{ field: "SpecificField3", format: "{0:c}" };
evaluates to the former of the comma delimeted "sub-expressions", for example:
var a = 1, b = 2;
var c = a, b;
alert(c === a);
and in your original code this directly translates to the first literal object being returned from the function while the later is "discarded".
(By the way, if you're not using the myParam argument you might as well not define it and not pass it in the call)
First return array, then use Array.prototype.concat to flaten it into array.
Is this a suitable solution for your problem?
$scope.getSpecificColumnsNotWorking = function (myParam) {
return [
{ field: "SpecificField2", format: "{0:c}" },
{ field: "SpecificField3", format: "{0:c}" }
];
}
columns: [].concat(
{ field: "Field1", width: "200px" },
{ field: "Field2", title: "Field 2", width: "80px" },
getSpecificColumnsNotWorking (parameter),
{ field: "Field4" });

Categories