How to set Values to FormArray in Angular 4 after it has been Initialized? - angular-reactive-forms

I have a formArray and I would like to set values to the array after I get the data at a later point in time but since I have the formArray initialized is it possible it set initial values to the formArray and how do I set the value if I have to
constructor(private fb: FormBuilder) {
this.businessForm = fb.group({
businessInfo: this.buildBusinessArray()
});
buildBusinessArray() {
this.businessInfo = this.fb.array([this.buildBusinessGroup()]);
return this.businessInfo;
}
buildBusinessGroup() {
return this.fb.group({
taxNumber: '',
legalName: '',
`enter code here`dbaName: '',
location: '',
});
}
}
This is how I am trying to set the values in the function. But it doesn't set the value it just throws an error
this.selected.forEach((selected) => {
this.businessForm.setValue ({
'taxNumber': this.merchantInfo[selected.merchantNumber].businessInfo.taxNumber,
' legalName':
this.merchantInfo[selected.merchantNumber].businessInfo.legalName,
'dbaName': this.merchantInfo[selected.merchantNumber].businessInfo.dbaName,
'location': this.merchantInfo[selected.merchantNumber].businessInfo.location
});
});
I am not sure what I am missing. Could someone please help me with this?

When you trying to use setvalue method. you need to set all members.
If you use your code then replace setValue with patchValue method.
your current code. I have updated method.
this.selected.forEach((selected) => {
this.businessForm.patchValue ({
'taxNumber': this.merchantInfo[selected.merchantNumber].businessInfo.taxNumber,
' legalName':
this.merchantInfo[selected.merchantNumber].businessInfo.legalName,
'dbaName': this.merchantInfo[selected.merchantNumber].businessInfo.dbaName,
'location': this.merchantInfo[selected.merchantNumber].businessInfo.location
});
});
You can also use setvalue but you need to initialise businessInfo property.
this.selected.forEach((selected) => {
this.businessForm.patchValue ({
businessInfo: '',//assign your value here
'taxNumber': this.merchantInfo[selected.merchantNumber].businessInfo.taxNumber,
' legalName':
this.merchantInfo[selected.merchantNumber].businessInfo.legalName,
'dbaName': this.merchantInfo[selected.merchantNumber].businessInfo.dbaName,
'location': this.merchantInfo[selected.merchantNumber].businessInfo.location
});
});

Related

Can I $watch a property once and then forget about it?

My component needs to act upon a property change once, during initialization. Subsequent changes to the property do not require any action.
I've currently solved this with a workaround like the one below. Is there a better way to $watch something once?
const Component = () => ({
property: ""
hasInitialized: false,
init() {
this.$watch("property", (value, oldValue) => {
if (!this.hasInitialized) {
// Go do something
this.hasInitialized = true;
}
});
},
});
export default Component;

using Fomik hook `useField` and `react-data-table-component` causes infinite loop

I am using react-data-table-component inside formik form to update new values. But the problem is whenever the MyTable component is re-rendered, the selectableRowSelected() callback is called, which triggers onSelectedRowsChange event in which I use helpers.setValue() to set value, which then makes MyTable component renders again. This whole process causes infinite loop, and I still don't have a solution for this.
function MyTable() {
const [data, setData] = useState([]);
const [field, meta, helpers] = useField({ name: "use" });
useEffect(() => {
fetch("https://reqres.in/api/users?page=1&per_page=3")
.then((res) => res.json())
.then((res) => setData(res.data));
}, []);
const handleChange = React.useCallback(({ selectedRows }) => {
let selectedIds = selectedRows.map(function (row) {
return parseInt(row.id);
});
selectedIds.sort();
console.log("🚀 ~ selectedIds", selectedIds);
// helpers.setValue(selectedIds, true); --> uncomment this will cause infinite loop.
}, []);
return (
<DataTable
title="User List"
columns={columns}
data={data}
selectableRows
selectableRowsHighlight
onSelectedRowsChange={handleChange}
selectableRowSelected={(row) => {
return meta.value.includes(parseInt(row.id));
}}
/>
);
}
CodeSandbox: https://codesandbox.io/s/goofy-tu-l1pxvb?file=/src/MyTable.jsx:375-1249
I think I've figured it out myself. But I will post it here in case anyone may encounter the same.
There is no way to stop this problem as the way RDT works is whenever selectableRowSelected is called, it will dispatch an action with type: SELECT_MULTIPLE_ROWS:
dispatch({
type: 'SELECT_MULTIPLE_ROWS',...
});
then in tableReducer, it returns toggleOnSelectedRowsChange as boolean value:
case 'SELECT_MULTIPLE_ROWS': {
...
return {
...state,
...,
toggleOnSelectedRowsChange,
};
which controls the trigger of onSelectedRowsChange event (as mentioned at comment in the source code):
useDidUpdateEffect(() => {
onSelectedRowsChange({ allSelected, selectedCount, selectedRows: selectedRows.slice(0) });
// onSelectedRowsChange trigger is controlled by toggleOnSelectedRowsChange state
}, [toggleOnSelectedRowsChange]);
Overall, solution for this problem is don't use formik with RDT for row selection, use another datatable lib.

How to get a variable to bind from xhr call response in VueJS?

Ok I'm a beginner at VueJS and I'm just trying to do a simple XHR call and bind the json data response to my variable...
I have a component App.vue and this part of the template I want to show the results of the json. bpi is the name of the variable
<div id="simulationPoints">
<h2 className="logTitle">Full Log:</h2>
{{ bpi }}
</div>
then my script
export default {
name: 'App',
data: () => ({
bpi: []
}),
mounted: () => {
axios.get(`https://api.coindesk.com/v1/bpi/historical/close.jsonp?start=2011-01-01&end=2018-02-01`)
.then(response => {
this.bpi = response.data.bpi
})
.catch(e => {
this.errors.push(e)
})
}
}
This doesn't seem to work. I'm using Axiom to fetch the data and assign the response, and this is how all the examples I found online did it, but the array object I have is still empty and it doesn't render on the page. I don't know whats the issue here? A Vue expert please help :)
There are sorts of problem in your code.
First, don't use arrow function on options property or callback since arrow functions are bound to the parent context, this will not be the Vue instance as you’d expect.
Second, use return statement in your data function.
Third, use created hook for inserting data after instance is created. mounted hook is called for mutation after DOM is rendered.
export default {
name: 'App',
data: function() {
return {
bpi: []
}
},
created() {
axios.get(`https://api.coindesk.com/v1/bpi/historical/close.jsonp?start=2011-01-01&end=2018-02-01`)
.then(response => {
this.bpi = response.data.bpi
})
.catch(e => {
this.errors.push(e)
})
}
}

Angular 2 async validator always invalid

I have the following form control with the simplest async validator I could write:
this.aliasCtrl = this._fb.control('', [(control: AbstractControl) => {
return new Promise(resolve => {
console.log(this.aliasCtrl);
resolve(null);
});
}]);
My form definition is:
this.contactForm = this._fb.group({
alias: this.aliasCtrl
});
My form control is always invalid.
Here's a plunker: http://plnkr.co/edit/vyr48ke7fWEUwrXy43tn?p=preview
I'm sure I've miss something but I cannot find what.
Thanks for help.
Change the code to:
this.aliasCtrl = this._fb.control('', null, (control: AbstractControl) => {
return new Promise(resolve => {
console.log(this.aliasCtrl);
resolve(null);
});
});
Pass null or empty array for validators (second parameter) and the async validator function as the third parameter.
Tested... Works!

Dojo Cache - Tree - Uncaught TypeError: object is not a function

I am trying to use a data store cache with a tree.
I am getting Uncaught TypeError: object is not a function error.
I have tested the data and it is being pulled correctly.
I have checked the JSON and it is also correct.
Where am I going wrong?
require(["dojo/store/JsonRest"
, "dojo/store/Memory"
, "dojo/store/Cache"
, "dojo/json"
, "dijit/tree/ObjectStoreModel"
, "dijit/Tree"
, "dojo/domReady!"],
function (JsonRest, Memory, Cache, ObjectStoreModel, Tree) {
var restStore = new JsonRest({ target: "/DataStore/", idProperty: "id" });
var memoryStore = new Memory({
idProperty: "id",
getChildren: function (object) {
return this.query({ parent: object.id });
}
});
var store = new Cache(restStore, memoryStore);
store.query({ type: "index" }).forEach(function (item) {
console.log(item.name);
});
var docModel = new ObjectStoreModel(
{
store: store,
getRoot: function (onItem) {
this.store.get("index").then(onItem);
},
mayHaveChildren: function (object) {
return object.type === "folder" || object.type === "root";
}
});
var docTree = new Tree({
model: docModel,
onOpenClick: true,
onClick: function (item) {
if (item.type == "link") {
OpenLink(item.link);
}
},
persist: false
}, "divTree");
docTree.startup();
});
This has to do how Cache works. The first time store.get() is called, it uses the JsonRest store which returns a Promise. A Promise has a then() function so there is no problem. The next time it's called, it uses the Memory store which returns your JavaScript object itself. Your JavaScript object has no then() function, so an error is thrown. This can be fixed by surrounding the store.get() in a when().
Try changing
this.store.get("index").then(onItem);
to
when(this.store.get("index")).then(onItem);
Take a look here for more details.

Resources