i am quite new to angular and am trying to get a value froma button displayed in the html via a function.
the button layout is:
`<button class="btn" id="btn-gold" (click)="value(9)"
name="mybutton" value="9">`
9
i am also calling the function in the html file like following: {{ value() }}.
this is my setup in the .ts file:
public value(a) {
console.log(a);
return a;
}
sadly i am not able to get any value displayed in my html file. i can see this in the console:
7
scoring.component.ts:18 undefined
scoring.component.ts:18 undefined
now to the question. why am i not able to see the value in my .html file as i can see the number in my console, and secondly why am i also getting per click two undefined values with it :/
chears,
ArcherMark
Have a property value in your TypeScript
value: number;
and have a function to set the value
setValue(value: number) {
this.value = value;
}
Now you can set the value with a button in the template
<button class="btn" id="btn-gold" (click)="setValue(9)" name="mybutton" value="9">
and display the value with a template binding
{{ value }}
If you do something like {{ value() }} you are calling a method not a property so angular is gonna evaluate that expression every time it checks for changes, which is associated with the DoCheck lifecycle hook thats why the console log prints 2 times the value,
The solution is to convert value into a property and have a getter and a setter and use two way data binding.
Related
Inside a .NET 5 blazor application I use a javascript library for barcode reading. When I press a button on blazor page I call javascript function. Javascript function reads the barcode and sets value of an input field.
There is an input field bound to string value:
<input id="result" #bind="#Received"/>
#code { private string Received { get; set; } }
A button click calls javascript function:
public async Task Start()
{
await JSRuntime.InvokeVoidAsync("startBarcodeReader");
}
Javascript function sets value of input field:
document.getElementById('result').value = "Barcode Value";
Everything works as I expected and I see barcode value on my screen. I would like to use Received when I click another button. However bound value is null. It is not set.
public async Task Add()
{
// Received is null
await Task.CompletedTask;
}
If I manually type something into input field then value of Received variable is set. It seems that binding is not set bound variable unless focus is lost.
How can I get the value I see in input field? I tried to use oninout event of inout field and did not work.
As a rule, your JS code should not interfere in any way with the rendering and bounding features of Blazor. Thus, you cannot assign a value to an input field in JavaScript and expect this value to pass to the bounding variable Received. This can never occur. How can Blazor know that the value of the input field has changed ! Is there any event listener attached to the input field that is to notify Blazor that a value has been entered ? None.
Solution: Pass the value to a Blazor method in which you can update the variable Received... After that the component will re-render, and the input field will show the same value inside it, but this time it is done by the rendering and bounding features of Blazor.
Note: You can employ DotNetObjectReference to call your JavaScript, passing it a reference to a C# object that defines a method to receive the value of the barcode when called from JavaScript.
I have axios callback and I want to update the property of vue object and I have 2 way binding between the input tag and the edited property so that text box is hidden or displayed depending the edited property. when I update edited property to false inside callback, the textbox won't be hidden. but textbox is hidden or displayed when I updated outside axios callback.
editBtnClicked: function (index) {
var promise = null;
axios.put('/rest/project', this.projects[this.currentIndex]).then(response => {
// textbox won't be hidden or displayed even if this statement is executed.
this.projects[this.currentIndex].edited = !(this.projects[this.currentIndex].edited);
});
// textbox is hidden or displayed when this statement is excuted.
// this.projects[this.currentIndex].edited = !(this.projects[this.currentIndex].edited);
}
Could anyone tell me why? and you can check the full code: https://gist.github.com/inherithandle/e61a5ab2809581a5d36de08b4e4349f1
My opinion is that is caused by the property edited of project item in projects array is added to the project dynamically.
Adding property to Ojbect
When adding the property to Object, you have to use $set.
Due to the limitations of modern JavaScript (and the abandonment of Object.observe), Vue cannot detect property addition or deletion.
However, it’s possible to add reactive properties to a nested object using the Vue.set(object, key, value) method:
Please try the below code in line 181 and other lines that changes edited of project item in your source code of github.
this.$set(this.projects[this.currentIndex], 'edited', false);
Your currentIndex always be 0, and your two if statements will always return false.
this is my controller code
myApp.controller('MainController',['$scope','$filter',function($scope,$filter){
$scope.handle = '';
$scope.lowercasehandle = $filter('lowercase')($scope.handle);
}]);
and this is the html part
<div class="container" ng-controller="MainController">
<div>
<label for="">What is your twitter handle?</label>
<input type="text" ng-model="handle">
</div>
<h3>www.twitter.com/{{lowercasehandle}}</h3>
</div>
but the same code works when I make lowercasehandle a function returning the lowercase version of handle. The below example works just fine when called in the html by invoking the function lowercasehandle() in the h3.
myApp.controller('MainController',['$scope','$filter',function($scope,$filter){
$scope.handle = '';
$scope.lowercasehandle = function() {
return $filter('lowercase')($scope.handle);
};
}]);
So why can't I directly update the value of lowercasehandle in the first case. Why do I need to use a function here? Whatever changes I make in the controller are supposed to show in the view right? So then why I am unable to achieve what I want using the first method?
In the first case,
$scope.lowercasehandle = $filter('lowercase')($scope.handle);
won't be called when $scope.handle is updated by the user and is assigned only once as. Making it into a function works as it is called on every digest cycle, which then uses the updated value of $scope.handle.
Because in first version you are calling filter only once and with '' string as the argument.
but if you make it a function and call it every time then it will return proper result everytime.
You define handle as an empty string and call the filter on the empty string thereafter. So the value can't change any more and will stay an empty string.
In your second example with the function, the function lowercases the string at the time it probably holds a string other than an empty string, so it can actually lowercase something.
Note that you can use the filter in your html too, in this situation it might be more suitable
<h3>www.twitter.com/{{lowercasehandle | lowercase}}</h3>
Conclusion:
The first try is a one time assignment, while the second one assigns every time things change.
I'm trying to watch the value of ng-model whilst also using the minlength validation. The problem is the model value remains empty/undefined until the validation criteria is met.
HTML
<input ng-model="xyz" minlength="8" />
JS
$scope.$watch('xyz', function(val) {
// Will either be undefined or a
// string bigger than or equal
// to 8 characters.
console.log(val);
});
I know I could just substring the element's value, but this code is implemented in a directive which uses $compile, so ideally I'd prefer to watch the model value.
Any thoughts on how to resolve this?
https://docs.angularjs.org/api/ng/directive/ngModelOptions
allowInvalid: boolean value which indicates that the model can be set with values that did not validate correctly instead of the default behavior of setting the model to undefined.
I'm trying to pass a scoped object property into a function in my controller and then change its value to either true or false depending on the current value. Then I want this value to be updated in the scope at the same time.
The problem that occurs is that I can't just use $scope.isBeingEdited in the function to update the scope, because it's present in an ng-repeat so it wouldn't know which one to update. And just setting the value of the parameter doesn't seem to update the scope.
I read this question which seems to state that this is not possible? Maybe I read it wrong but surely there must be a rather simple way of achieving this? This is causing me problems on more than one front so it's time that I solve this issue.
Here's a dumb version of my markup, containg a title, an input and an edit "button":
<div ng-repeat="bodypart in body">
<h3 ng-hide="bodypart.isBeingEdited" ng-bind="bodypart.name"></h3>
<input ng-show="bodypart.isBeingEdited">
<span ng-click="setEditState(bodypart.isBeingEdited)">Edit</span>
</div>
When I click on "edit" then this should run, passing bodypart.isBeingEdited as the variable to do a value check for:
$scope.setEditState = function(item) {
// Check if item is true or false
// and set it accordingly
item ? item = false : item = true;
}
How can I ensure that the scoped variable that gets passed to this function gets updated when item gets updated?
You can pass item instead of property isBeingEdited and use it in code accordingly:
<span ng-click="setEditState(bodypart)">Edit</span>
Controller
$scope.setEditState = function(item) {
item.isBeingEdited = !item.isBeingEdited;
}
Since objects are passed by reference, you should be able to do something like this.
<div ng-repeat="bodypart in body">
<h3 ng-hide="bodypart.isBeingEdited" ng-bind="bodypart.name"></h3>
<input ng-show="bodypart.isBeingEdited">
<span ng-click="toggleBodyPartState(bodypart)">Edit</span>
</div>
$scope.toggleBodyPartState = function(bodyPart) {
bodyPart.isBeingEdited = !bodyPart.isBeingEdited;
}