I have an array of objects that includes an element with an object and I'm looking to display the name of the object on a selectable dropdown using ng-select. I can console log everything as expected, however when I try to display the data I am only able to show [object, object]. The correct number of objects.
HTML -
<ng-select
[searchable]="false"
bindValue="id"
bindLabel="medications.items"
[items]="selected"
[(ngModel)]="serviceUsersMedication">
</ng-select>
TS -
onSelect({selected}) {
this.selected = selected;
const filteredMeds = this.selected.filter(item => {
return item.medications;
});
this.serviceUsersMedication = filteredMeds.map(item => {
return item.medications;
});
console.log('Selected:');
console.log(this.selected);
}
You're using the same variable for [items] (the collection ng-select uses to display the options) as for [(ngModel)] (used for storing/displaying the SELECTED (1) item).
You have to split this:
[items] should refer to the collection
[(ngModel]) should refer to your selected item.
Your ng-select should look like this:
<ng-select
[searchable]="false"
bindValue="id"
bindLabel="name"
[items]="medications.items"
[(ngModel)]="selected">
</ng-select>
Assuming you have a name attribute in the items array of medication, else change it to the attribute that makes sense to show.. selected is already containing the selected item, no need to filter for that.
Also assuming you're using ng-select from #ng-select/ng-select
Related
I have an array of items that a user selects from a dropdown and is saved to the db. The list of items are saved in an uppercase format. I'm looking to find an item from a db stream and return it in a 'friendly format'.
TS --
enumMap() {
const oldValue = this.rows.map(item => item.oldValue);
const savedItem = oldValue.find(element => element === 'SAVEDITEM');
if (savedItem) {
return 'Saved Item';
}
}
HTML -
<ngx-datatable-column name="Previously" prop="changedFrom" [minWidth]="50" [maxWidth]="150">
<ng-template ngx-datatable-cell-template let-rowIndex="rowIndex" let-value="value" let-row="row">
<span> {{row.oldValue}} </span>
</ng-template>
</ngx-datatable-column>
You can use regexes to do that along with a pipe.
But right now, you can't really.
SAVEDITEM has no delimitor and only a human (or a smart IA) would be able to do so.
Try saving it at least as SAVED_ITEM so that you know when to split it.
As for the pipe, the internal titlecase pipe should do the trick easily, no need to write a custom one.
In Angular, how to use *ngIf to check whether a JSON value includes a certain string, and then show them a certain URL ? In my case I have a object name called campaigns.description which has a value that includes a description. I want to see whether a given string, for example "one beam" is included in that description and show an URL based on that.
So not the way that the value equals a certain string, but the text that is held within the value includes a certain string.
You can use indexof() function to check the existence of some substring inside a string. This function returns '-1' if the substring is not present in the string.
<label *ngIf="campaigns.description.indexOf('One Beam') != -1 ? true : false">{{urlToShow}}</label>
You could generally use indexOf to check whether a string contains a sub-string.
console.log("Sample string".indexOf('string'));
console.log("Sample string".indexOf('not'));
The Angular part:
Trivial (not recommended)
Trivial solution is to check directly in the *ngIf condition
<div *ngIf="campaigns.description.indexOf('one beam') !== -1; else other">
<!-- contains the sub-string -->
</div>
<ng-template #other>
<!-- does not contain the sub-string -->
</ng-template>
However binding a function to *ngIf directive with default change detection strategy would trigger the function for each change detection cycle. It might lead to performance issues.
Additional property (recommended)
You could introduce additional property to hold the result of the condition in the controller and use it in the template.
Controller (*.ts)
// I assume `campaigns` is initialized in a subscription
ngOnInit() {
someObservable.subscription(
(res: any) => {
this.campaigns = {
...res,
subString: res.description.indexOf('one beam') !== -1
}
},
(error: any) => { }
);
}
Template (*.html)
<div *ngIf="campaigns?.subString; else other">
<!-- contains the sub-string -->
</div>
<ng-template #other>
<!-- does not contain the sub-string -->
</ng-template>
I would like to have an ng-select which allows only numbers while typing/search as it is used only for Year field
<ng-select class="single" [items]="years" [multiple]="false" bindLabel="name" #select >
Do we have a way to control what user can type ?
You can check by the ng-select output (search)="myListenerFunction($event)" this will catch an object who look like
{
term: string,
items: yourObject[]
}
term is what the user serch and item the result of the search.
You can see it there: https://ng-select.github.io/ng-select#/events
I want to allow a user to provide a list of one-word attributes without parameter values. For example,
<container row crosscenter wrap spacearound ...>
which results in something like this in container.html
<div [ngClass]="{ 'flexDisplay': true, 'directionRow': isRow, 'directionCol': isCol, 'contentSpaceAround': isSpaceAround}" ...>
What I'm missing is how to set
#Input('row') isRow = false;
to true if 'row' was present in the container line.
Any ideas?
Thanks in advance.
Yogi
This can be handled in ngOnChanges. The value can be assigned either back to input property or to some object that will be passed to ngClass
ngOnChanges(changes: SimpleChanges) {
if ('foo' in changes) {
this.options.foo = true;
}
}
Since there's no way how inputs can become unassigned, there's no reason to provide bindings for them. #Attribute can be used instead:
constructor(#Attribute('foo') public foo: boolean|null) {
this.foo = (foo != null);
}
Using attributes for regular options isn't a good decision, design-wise. This prevents from setting them dynamically. Instead, it is always preferable to accept options input. If all options are supposed to be flags, it can be a string input that will be split and processed in ngOnChanges, like:
<container options="row crosscenter wrap spacearound">
or
<container [options]="'row crosscenter wrap spacearound'">
I think the answer to my question is to create directives for each of the "one-word" tags (attributes) I want to use.
:-)
I have created a form which allows the user to add additional text-inputs by clicking a button. The FormControls behind these inputs are stored in a FormArray inside of a FormGroup.
I want to provide a default value for these inputs, that is going to be submitted if they are pristine. If the user changes the value of the input, which changes it to dirty, I do not want the default value to be submitted or displayed.
I currently am displaying the inputs like this, as the placeholder attribute does exactly what I want, displaying the default name, only if the input has not been changed.
<div
formArrayName="names"
*ngFor="let server of names.controls; let i = index; trackBy:trackByFn">
<span>{{ i + 1 }}</span>
<input
type="text"
formControlName="{{i}}"
placeholder="{{defaultName}}">
</div>
To validate the names I have created the following validation function:
export function validateServerName(form: FormGroup): ValidationErrors | null {
const names: string[] = form.value[CREATE_FORM_KEY_NAMES];
for (const name of names) {
if (name.trim() === '') {
return {
invalidName: true
};
}
}
return null;
}
Here I am having trouble figuring out if the element is dirty or pristine, as form.value[key] only returns a string array, not an array of the FormControls.
I am looking for either an easier way to do what I am trying to achieve, or a way to validate the form properly.
you can check the control status using
if touched is true then its dirty
this.form.get('controlname').touched
and for pristine you can check like
this.form.get('controlname').pristine
UPDATE
for form array it will be something like
let val = this.user.get('<FormArray>') as FormArray;
console.log(val.at(index));
you can now use pristine and touched on this variable