Form array value changes is not working. I can't console the value inside subscriber method.
Here is my basic form array code below.
ordersData = [
{ id: 100, name: 'order 1' },
{ id: 200, name: 'order 2' },
{ id: 300, name: 'order 3' },
];
this.formGroup = this.formBuilder.group({
testControl: this.formBuilder.array([])
});
get formGroupControl() {
return (this.formGroup.get('testControl') as FormArray);
}
private addFormControl() {
this.ordersData.forEach((o, i) => {
(this.formGroup.get('testControl') as FormArray).controls.push(this.formBuilder.control(''));
});
}
I've called this addFormControl() function inside the ngOnInit() and if I try to see the valuechanges using this following way
this.formGroup.get('testControl').valueChanges.subscribe(value => {
console.log('log', {value});
});
this console is not working..
Walk me through the right way of handling form array
I was having the same problem (I think), forms added to the formArray through formArray.controls.push didn't work, I fixed by using formArray.push instead
Related
I am having an array with following values:
[
{
'Admin1': {
id: 'fa1b2731'
},
'Admin2': {
id: '7b5ab064'
},
'Admin3': {
id: '9f462511'
},
'Admin4': {
id: 'aa82421d'
},
'Admin5': {
id: '34cb2b'
},
'Admin6': {
id: 'ff71ffdd'
},
'Admin7': {
id: 'b57ac9e7'
}
}
]
The code i am trying to retrieve each user id from above array is throwing an error->expected undefined not to be undefined
Following is the code snippet:
if (userArray) {
for (const user of Object.values(userArray)) {
const delUserRes = await userApi.deleteUserById({
token: accessToken,
organizationId: orgid;,
userId: user.id
});
the above method reads the userarray corectly but never assign each id to userId form user.id and throws error
The array in example is having one item, what i mean to get user.id you should call array[0].['Admin1'].id. In your code you doing it like array.['Admin1'].id, so thats why it can't find user.id.
try something like this
if (userArray) {
for (const user of Object.values(userArray[0])) {
const delUserRes = await userApi.deleteUserById({
token: accessToken,
organizationId: orgid;,
userId: user.id
});
Your all the user are in single element of array object at 0 index.
try below code
for (const user of Object.values(userArray[0])) {
console.log(user)
}
Basically you are trying to get values from an object inside an array, so the Object.values doesn't make sense in your code. You can simply use userArray[0] in your for loop or map like:
var data = [ { 'Admin1': { id: 'fa1b2731' }, 'Admin2': { id: '7b5ab064' }, 'Admin3': { id: '9f462511' }, 'Admin4': { id: 'aa82421d' }, 'Admin5': { id: '34cb2b' }, 'Admin6': { id: 'ff71ffdd' }, 'Admin7': { id: 'b57ac9e7' } } ]
Object.values(data[0]).map(user => { //your logic here } );
I am using Syncfusion Angular Scheduler and I added a custom field, a dropdown list, and I want to populate that with dynamic data from my MongoDB. This is my code:
onPopupOpen(args: PopupOpenEventArgs): void {
if (args.type === 'Editor') {
if (!args.element.querySelector('.custom-field-row')) {
....
let dropDownList: DropDownList = new DropDownList({
dataSource: [
{text: this.clients[0].company, value: this.clients[0].company},
{text: this.clients[1].company, value: this.clients[1].company},
],
fields: {text: 'text', value: 'value'},
value: (<{ [key: string]: Object }>(args.data)).Client as string,
floatLabelType: 'Always', placeholder: 'Client'
});
}
}
However, I want to add them dynamically without specifying the 0th index or 1 because i dont know how many clients the user will have. So I want to display the company property of every client (Object). when I add a for loop or ForEach in dataSource, it gives errors all over the place. Also, this.clients.map(client => ({text: client.company, value: client.company})), gives me an empty Dropdown list. If you need more info, please let me know.
ngOnInit() {
this.clientService.getClients().subscribe((data : any) => {
this.clients= data.client;
});
}
We have validated your reported problem at our side by preparing the CRUD sample with MongoDB as a service. In that, we have using Dropdown Component as an additional (custom) field and the data source for the custom field is assigned from the Observable Data Services and it can be downloaded from the following link.
Code snippet:
ngOnInit(): void {
this.selectedDate = new Date(2018, 1, 14);
this.eventSettings = { dataSource: this.dataManager };
const clientObservable = this.clientService.getClient();
clientObservable.subscribe((client: client[]) => {
this.dropDownDataSource = client;
});
}
onPopupOpen(args: PopupOpenEventArgs): void {
if (args.type === 'Editor') {
// Create required custom elements in initial time
if (!args.element.querySelector('.custom-field-row')) {
let row: HTMLElement = createElement('div', { className: 'custom-field-row' });
let formElement: HTMLElement = <HTMLElement>args.element.querySelector('.e-schedule-form');
formElement.firstChild.insertBefore(row, args.element.querySelector('.e-title-location-row'));
let container: HTMLElement = createElement('div', { className: 'custom-field-container' });
let inputEle: HTMLInputElement = createElement('input', {
className: 'e-field', attrs: { name: 'EventType' }
}) as HTMLInputElement;
container.appendChild(inputEle);
row.appendChild(container);
let drowDownList: DropDownList = new DropDownList({
dataSource: this.dropDownDataSource,
fields: { text: 'company', value: 'companyValue' },
value: (args.data as { [key: string]: Object }).EventType as string,
floatLabelType: 'Always', placeholder: 'Event Type'
});
drowDownList.appendTo(inputEle);
inputEle.setAttribute('name', 'EventType');
}
}
}
Sample: https://www.syncfusion.com/downloads/support/directtrac/269086/ze/sample-525591979
Kindly try the above sample and if you have any other concerns please revert for further assistance.
I want to empty the array in the state before adding to it again
this.state = {
arrayOne = [
{
name: 'first n',
last: 'last n'
},
{
name: 'first Name',
last: 'last Name'
}
]
}
this.setState({arrayOne: []}) //not emptying the array
this.setState({arrayOne: [...arrayOne.splice()]}) //also not working
Why do you say its not working? The syntax looks fine and should work
Please note that setState is an async function, you need to wait for the update to complete in order to see change.
You can pass a callback function to setState, that will get executed when the state was set, like so
this.setState({
blah: 'something new'
}, () => {
console.log(this.state.blah) // will print 'something new'
}
})
You will not see immediate change if you do it like this:
this.setState({
blah: 'something new'
})
console.log(this.state.blah) // this will print whatever 'blah' was previously set to, and not 'something new'
Try like this..
this.state.arrayOne = [];
or
this.state['arrayOne'] = [];
I'm trying to setup a multi select control from bootstrap-vue and bind it to a JSON object. The problem is that I need a computed value to get my json data format in a int array for the multiselect selected values and vice versa. Using such a computed property means that I change date while rendering which leads to an infinite loop.
Currently I created a computed property which has a getter which transforms the JSON object array in a integer array as well as a setter which does the opposite. In my example code the JSON object only contains the id, but in my production code there are a lot of other fields inside a "company".
<template>
<b-form>
<b-form-select
:id="`input-companies`"
v-model="companiesSelected"
multiple
:select-size="4"
:options="availableCompanies"
></b-form-select>
</b-form>
</template>
<script>
const availableCompanies = [
{ value: 1, text: 'company1' },
{ value: 2, text: 'company2' },
{ value: 3, text: 'company3' },
{ value: 4, text: 'company4' }
]
export default {
data () {
return {
employee: { id: 1, name: 'test', companies: [ { id: 1 }, { id: 2 } ] },
availableCompanies: availableCompanies
}
},
computed: {
companiesSelected: {
get () {
if (this.employee.companies == null) {
return []
}
return this.employee.companies.map(company => { return company.id } )
},
set (newValue) {
if (newValue == null) {
this.employee.companies = []
} else {
this.employee.companies = newValue.map(companyId => { return { id: companyId } })
}
}
}
}
}
</script>
The setting of this.employee.companies leads to a infinite loop. I don't really know how to avoid this. Does anyone know how to overcome this issue?
I basically split your computed set into the #change event and it seems to be working.
The #change event should only fire from user interactivity and should therefor cause the loop.
https://codepen.io/Hiws/pen/agVyNG?editors=1010
I'm not sure if that's enough for you, as i didn't take the extra fields on a company into consideration when writing the example above.
I´m gonna break my head with a stone ^^"
I have this code:
this.af.database.list('/Documentos', { preserveSnapshot: true })
.subscribe(snapshots => {
snapshots.forEach(snapshot => {
console.log(snapshot.key, snapshot.val());
});
})
With that I extract all the data correctly, but now I want to add to an object array or something like that (I started few weeks ago with Firebase + Angular2).
I wanna fill that array to load the [ng2 smart table] and if I´m thinking partially well with a properly well-formed array I will fill the table but I don´t know how. Hope anyone can help.
If you want an map (object) with key: value, you can easily do this with Array.prototype.reduce():
const map = snapshots.reduce((map, snapshot) => {
map[snapshot.key] = snapshot.val();
}, {});
Well, according to the example : https://akveo.github.io/ng2-smart-table/#/examples/using-filters ...
(You can find the source code here: https://github.com/akveo/ng2-smart-table/blob/master/src/app/pages/examples/filter/basic-example-source.component.ts)
... you have to put your data in a JSON object :
settings = {
columns: {
id: {
title: 'ID',
filter: false,
},
name: {
title: 'Full Name',
filter: false,
},
username: {
title: 'User Name',
filter: false,
},
email: {
title: 'Email',
filter: false,
}
}
};
data = [
{
id: 1,
name: 'Leanne Graham',
username: 'Bret',
email: 'Sincere#april.biz',
},
{
id: 2,
name: 'Ervin Howell',
username: 'Antonette',
email: 'Shanna#melissa.tv',
}
];
"settings" contain your columns names and "data" must match the columns from "settings".
It would be easier if we knew a bit more of your code (columns of your table + data returned by your service), but I assume something like that would work :
data = [];
this.af.database.list('/Documentos', { preserveSnapshot: true })
.subscribe(snapshots => {
snapshots.forEach(snapshot => {
data.push(
{ [snapshot.key]: snapshot.val() }
);
});
})
Please note that this will create a JSON array with only one key/val per row. We do need to know more about your data to give you a propre answer.
Ok, I found the solution with a simple Array() x)
this.af.database.list('/Documentos', { preserveSnapshot: true })
.subscribe(snapshots => {
snapshots.forEach(snapshot => {
let length = todo.documentos.push(snapshot.val()); // documentos is an array in the class
todo.source.load(todo.documentos);
});
});