sign dynemic key.value in ngFor - javascript

I'm trying to assign a dynamic object value named destination inside ngFor like this:
<div *ngFor="let obj of object.destination"><p [innerHTML]="cont.disc"></p> </div>
This destination is supposed to change dynamically using property binding (it works)
In my component.ts there is a function which assigns the dynamic value I get to the destination value, and connect it to the object key:
public getDestination() {
this.destination = this.to;
return (this.destination = `${this.content}.${this.destination}`); }
But all I get is that {{ object.destination }} equal to
<p>[object Object].india</p>
How can I make the object value dynamic so it will change depending on the property binding?

Related

Why is typescript setting my value to a 'undefined' string instead of an undefined?

I have a select dropdown where I set the first value to a undefined.
But the problem is if I select a dropdown value and then go and select the first value ('All') then my bound variable ends up becoming a string 'undefined' and it actually changes it from a number to a string.
memberParams.membership // is a :number and I don't want it to be converted to a string
and memberTypes is a name/value pair
export interface IMemberType {
value: number;
name: string;
}
Why is this and how can I prevent it?
this.memberTypes = [{value: undefined, name: 'All'}, ...response.memberships];
<select class="form-control custom-select w-100" name="memberType" [(ngModel)]="memberParams.membership">
<option *ngFor="let memberType of memberTypes" [value]="memberType.value">
{{memberType.name}}
</option>
</select>
The HTML value property is always either a number or a string. So, there is no way to fix it in the Angular template. However, inside your component you can have a setter and getter which can change the value correctly.
Inside your component:
get membership() {
return this.memberParams.membership;
}
set membership(value: string | number) {
this.memberParams.membership = val === "undefined"? undefined : value;
}
You only need to make one small change in your template, which is to change the [(ngModel)] binding from memberParams.membership to just membership.

Angular 6 calling method and asigning value to variable inside *ngFor

I want to call a method inside ngFor and want to assign the return value to a local variable. I tried this approach:
<div *ngFor="let card of partNumberPlanningCards; let i = index" class="partnumber-basic-card">
<div
*ngFor="let scope of containerScopeLineItems; let lineItem = getOperatingWeightBy(scope.containerScopeId, card.typeId)">
</div>
</div>
But it's showing this error:
Parser Error: Unexpected token (, expected identifier, keyword, or string at column 74 in [let scope of containerScopeLineItems; let lineItem = getOperatingWeightBy(scope.containerScopeId, card.typeId)] in ng
You can store function returned value in any of the attribute of element and use the element reference to get value.
<div *ngFor="let card of partNumberPlanningCards; let i = index" class="partnumber-basic-card">
<div *ngFor="let scope of containerScopeLineItems" #lineItem [title]="getOperatingWeightBy(scope.containerScopeId, card.typeId)">
{{lineItem.title}}
</div>
</div>
Here title has been used but you can use any of valid attribute of element.
What are you trying to do here? Calling a function within ngFor to update DOM is certainly a bad practice to do.
As it looks, you want to filter based on the containerScopeId and typeId, you could simply do this and assign to a variable in the component.ts level rather than calling a function in the template.
Just declare a variable lineItem and use array.find() with your conditions to get the matching item.
Not sure if it helps you. But just tried something.. You can create a ng-template and use ng-container to display the template.
HTML:
<div *ngFor="let card of partNumberPlanningCards;" class="partnumber-basic-card">
{{card?.typeId}}
<div *ngFor="let scope of containerScopeLineItems;">
<ng-container *ngTemplateOutlet="eng; context: getOperatingWeightBy(card.typeId, scope.containerScopeId)"></ng-container>
{{scope?.containerScopeId}}
</div>
<ng-template #eng let-obj='value'>
{{obj}}
</ng-template>
TS:
export class AppComponent {
partNumberPlanningCards = [
{typeId : 'xx'}
]
containerScopeLineItems = [
{containerScopeId : 2}
];
getOperatingWeightBy(a,b){
return {value:a+b};
}
}
https://stackblitz.com/edit/angular-ngfor-loop

how to set an initial value for getter in TypeScript

I have a getter to return a value that is calculated in another function. It has the form like this:
private get numErrors() {
return calculateErrors(key);
}
In my html I have {{ $ctrl.numErrors }}. I am using AngularJS. This renders {{ $ctrl. numErrors }} for a few seconds before the value numerical value is calculated and displayed. Is there a way I can get it to initially display 0 before I get a return value?
You could potentially get around this via ng-cloak.
But instead of having numErrors() as a getter directly returning your other function's results why not do something like this? Have calculateErrors() get called in your logic where you need it to and have it set the value. This will be automatically updated on your template.
numErrors: number = 0;
calculateErrors(key) {
// Do calculation
numErrors = resultOfCalculation;
}
Considering that it is numeric value and it shouldn't be checked if it strictly equals to undefined, it can be
private get numErrors() {
return calculateErrors(key) || 0;
}
Or
{{ $ctrl.numErrors || 0 }}

Change entire object in ng-repeat function AngularJs

Hello I have a questions on ng-repeat on Angularand function for change value.
I have this ng-repeat that cycling a ObjectArray and have a button for reset value.
<div ng-repeat="element in data.elements">
<button ng-click="reset(element)" >reset</button>
</div>
Where data.elements is array of objects example:
[{id:1, name:"element1"},{id:2, name : "element2"}];
In my Controller I set function Reset in $scope that should do a copy of object passed to an default object:
$scope.reset = function(el){
$scope.defaultObject = {id:500, name:"default"};
el = angular.copy($scope.defaultObject);
}
But doesn't work, but if I do:
$scope.reset = function(el){
$scope.defaultObject = {id:500, name:"default"};
el.name = $scope.defaultObject.name;
}
It work.
So I would like that when I do (in this example):
el = angular.copy($scope.defaultObject);
have the object el equals to object $scope.defaultObject my question is, Can i copy entire object without cycling all properties?
You're passing an object to the reset function, then you're overwriting this object. That's it, nothing happens because it won't affect the original object, which is in the data.elements array.
You need to use a different approach. Track the element by its index :
<div ng-repeat="element in data.elements track by index">
<button ng-click="reset(index)" >reset</button>
</div>
...then amend data.elements[index]:
$scope.reset = function(index){
$scope.data.elements[index] = {id:500, name:"default"};
}
are you saying, your updated object does not reflect on the UI? you can try forcing the scope update by running $scope.$apply() after you have assigned the object.

assign a object to select value - ng-options

I have a object like this
var myObject = {'123':'something','345':'something else'}
I need to render it as:
<option value={'123':'something'}>something</option>
Here is what i have tried:
ng-options="someObj as label for (id,label) in myObject
Doesn't work!
The model gets the 'label' and not the whole object. Is it even possible to assign a object to value attribute of a SELECT element?
EDIT
Filter for object of the form: {'123':'something','345':'something else'}
.filter('putKeysandValues',function(){
return function(options){
var arr = [];
angular.forEach(options,function(value,key){
arr.push({'key':key,'label':value})
});
return arr;
}
});
You will need to provide an object with key & value attributes to ngOptions. For this you will need to modify the structure of your object to actually have this attributes.
One way is using a filter that returns a valid array for ngOptions:
ng-options="option.label for option in data.availableOptions | putKeyAndValue"
You can check out this plunker with a working filter.
If input is:
[{'123':'something'}, {'345':'something else'}]
Then output is:
[{"123":"something","id":123,"label":"something","$$hashKey":"object:3"},{"345":"something else","id":345,"label":"something else","$$hashKey":"object:4"}]
If you want to remove the obsolete id attribute, then use this filter.
With input the same input, it will return this:
[{"id":123,"label":"something","$$hashKey":"object:3"},{"id":345,"label":"something else","$$hashKey":"object:4"}]
If you still need to return a new array, then do not do it on the filter. In that case you can process the data before passing it to the view, all in the controller like this.
With input:
{'123':'something', '345':'something else'}
Output this:
[{"id":123,"label":"something"},{"id":345,"label":"something else"}]
Using select as something for a (key,value) in set of Values
ng-options="key as value for (key,value) in myObject"
This will put key into the option value and value into label. With that you need to also use ng-model and ngChange. Since you can't pass objects into values, idea is to do that in your controller.
<select ng-model="val" ng-change="changeVal(val)" ng-options="key as value for (key,value) in ops">
In your controller you already have myObject you are gonna add selected item and changeVal function
<script>
var selectedObject;
$scope.changeVal = function(val){
selectedObject = {};
selectedObject[val] = myObject[val];
}
</script>
It's a workaround without putting object into value attr since it is a string.

Categories

Resources