I want to set #Input parameters optional.
For example:
Child1.html:
templateUrl:'common-html.html'
Child1.TS:
currentValue : boolean = true;
CASE 2:
Child2.html:
templateUrl:'common-html.html'
Child2.TS:
// Not declared **currentValue**
Common-HTML.html:
<app-master [isLogEnabled]="currentValue"></app-master>
But above changes giving an error while AOT:
Property 'isLogEnabled' does not exist on type Child2.Component
So I cannot change HTML of :
<app-master [isLogEnabled]="currentValue"></app-master>
I would do:
App-Master-Component.ts
#Input() isLogEnabled: boolean = false; // can change false to true, null or w.e. depending on what you want as the default
// if consumer passes in a value, it will be overridden
Then in Child2.component.html
<app-master></app-master>
You cannot bind [isLogEnabled]="currentValue" if currentValue does not exist in the Child2.component.ts file.
You can't provide property that you didn't declare.
But you can use something like this:
<app-master [isLogEnabled]="currentValue || false"></app-master>
Or inside component you can create getter:
get isLogEnabled() {
return this.isLogEnabled || false;
}
Or you can try to use '?'
#Input() isLogEnabled?: boolean;
Related
I have a component that has 2 checkboxes that in each change event - aside text is changed.
I want to avoid double code so I created a function that receive two arguments the chackbox model and text to change but it seems that the value are passed by value.
Is it possible to pass it by reference? if not - what it the best-practice solution?
<input type="checkbox" id="aa" [(ngModel)]="checkboxOne" (change)="genericOnChange(checkboxOne,textOne)">
{{textOne}}
<input type="checkbox" id="nn" [(ngModel)]="checkboxTwo" (change)="genericOnChange(checkboxTwo,textTwo)">
{{textTwo}}
export class AboutComponent implements OnInit {
constructor() { }
checkboxOne = false;
checkboxTwo = false;
textOne = '';
textTwo = '';
ngOnInit() {}
genericOnChange(checkboxModel,componentProperty){
if(checkboxModel){
componentProperty ="pew pew pew!"
}
else{
componentProperty ="laser gun off!"
}
}
}
Please see stackbliz (about.component)
It’s passing the value because there isn’t a reference, it’s a primitive (you don't have a pointer like you would in C). You could create an object, or you could pass the variable name in as a string and do:
this[myVariable]. I would recommend the former (an object), as you could have a checkbox object with both checkboxes as properties:
checkboxes = {one: true, two: false}
You could create a wrapper object around your checkboxProperties, and pass that reference as a single parameter to your genericOnChange(...) function
genericOnChange(chk:CheckboxProperties){
if(chk.checked){
chk.name ="pew pew pew!"
}
else{
chk.name ="laser gun off!"
}
}
Now you are modifying a property of the object, and not a primitive string. Your changes will be reflected on the template as you are expecting.
Full example below:
https://stackblitz.com/edit/angular-basic-tutorial-r7eaup?file=app%2Fabout%2Fabout.component.ts
I use the app-somecomponent in the following way
<app-somecomponent required></app-somecomponent>
How do I check if app-somecomponent has the required attribute from the app-somecomponent.component.ts? I don't wan't to use any value for the required attribute (so [required]="true", for instance is not allowed)
About the - AngularJS equivalent for hasAttribute()? - the $attr is not available in the newer versions of Angular.
Try
#Input() required;
isRequired: boolean;
ngOnInit() {
this.isRequired = this.required !== undefined;
}
StackBlitz
If there is an option that required can take a value, try this
required: boolean;
constructor(#Attribute('required') required: boolean) {
this.required = required;
}
You could use viewchild decorator to get all attributes from your component
#ViewChild('localref', {static:true}) localref: ElementRef;
ngOnInit() {
console.log(this.localref)
}
Template:
<app-somecomponent required></app-somecomponent>
Here is the working demo for the same demo
check console to get your answer.
I have computed property in my data this.coinPairingOptions that needs to render its radio buttons based on some of the other fields in this schema. I have reduced the amount of code in the file to save space.
data: function () {
return {
schema: {
{model: "symbolPair", type: "radios", label: "Pair with", values:
this.coinPairingOptions, required: true}
},
computed: {
coinPairingOptions() {
console.log("computing coinPairingOptions")
let coin = this.model.symbol.toUpperCase();
let options = [];
if (this.model.exchange === 'Coinbase') {
options = this.getCoinbasePairs
} else if (this.model.exchange === 'Binance') {
options = this.getBinancePairs
} else {
}
console.log(options.get(coin));
return options.get(coin);
},
}
In the dev tools I can see the computed property changing to the correct values however it is not changing in the data. Apparently, this is appropriate behavior, but what is a way around this? I have tried putting {{this.coinPairingOptions}} in the html and it errors because it's a computed property with not value initially.
Any help would be appreciated!
You can't use computed property in data, because data evaluates before the computed properties did.
You can use a watcher to achieve the intended result. Have a look at the documentation, you can add the argument immediate to trigger the callback immediately with the current value of the expression.
Computed properties are already accessible in the template by using {{}}. You don't need to put a this in front of the computed.
I want so set a boolean value I either get from a property in an options object, or if this is not defined want to set a default value.
const raw = options.rawOutput;
If options.rawOutput is not set, the default value should be true.
Problem is: the options object may not exist at all.
Im looking for a more elegant solutions than something like this
if (options) {
if (options.rawOutput) {
raw = rawOutput;
}
} else {
raw = true;
}
You could check if options exists and if the property rawOutput exists, then take that value, otherwise take true.
raw = options && 'rawOutput' in options ? options.rawOutput : true;
or the same but without conditional (ternary) operator ?:.
raw = !options || !('rawOutput' in options) || options.rawOutput;
I would like to use typeof check:
const raw = ((typeof options == 'undefined') || (typeof options.rawOutput == 'undefined'))? true:options.rawOutput;
Using the power of ES6:
const { rawOptions: raw = true } = options || {};
using object deseructuring to get the rawOptions and assigning it to raw variable and with a default value of true
Try this in case you want to assign false if options is exists but rawOutput is not.
const raw = options ? (options.rawOutput ? rawOutput : false) : true;
You can do this using just logical operators,
const raw = options && options.rawOutput || true;
This would set raw to true in case either of options or options.rawOutput is falsy.
When we discuss about options, nowadays the approach is having always the object defined, to defaults at least. So, for example, in your case, you will have:
// list of all defaults value for options
const defaultOptions = {
rawOutput: true
}
// assuming you are in a function when you get the options
function doSomething(userOptions) {
// here you will have all the options, with `userOptions`
// overrides the default options if they're defined.
const options = {...defaultOptions, ...userOptions};
if (options.rawOutput) {
// do stuff
}
}
This is helpful especially when you have more than one options to pass, and you could have defaults for most of them. In this way, you don't have to check if any object or properties exists every time, and you also have a clear list of the options' default that you can change – or get from a JSON – without impact your code.
I'm working on a external API, where the default value of a object is null.
location.recipt = null;
But I need to set location.recipt.printRecipt to true, I created a fiddle and figured out unless I make location.recipt = {} I wont be able to set printRecipt, is there any other solution for this?
Because if that is the case I need to make 2 calls to the API, once to change from null to empty object {} and then again to update the data.
Fiddle : https://jsfiddle.net/bdeepakreddy/nwemtwtu/
location.recipt={
printRecipt : true
};
I suggest to use a check first
location.receipt = location.receipt || {};
location.receipt.printRecipt = true;
No. null is null (nothing), and you can't set properties on nothing. Instead, you could make your default value be an object with a value property:
location.receipt = { value: null };
You can do it in JavaScript in one statement:
var location2 = { recipt: { printRecipt: true } };
console.log(location2);