AngularJS Expression Not Displaying - angularjs

I'm simply trying to get an AngularJS expression to display on screen. However, nothing shows up between the curly braces. I've inspected the app with ng-inspector and although I see an object being created with an ng-model directive, I can't display the value with the object key.
Furthermore, for testing purposes, I can't even get a simple math expression to display either.
Here's what I'm working with.
<body ng-app="angularApp">
<div ng-controller="firstCtrl">
<input ng-model="project.completed" type="checkbox">
<input ng-model="project.title" type="text" placeholder="Project Title">
<label>
{{project.title}}
1+2={{1 + 2}}
</label>
<input ng-model="project.time" type="text" placeholder="Project Time">
<label for="">{{project.time}}</label>
<button ng-click="helloWorld()">Press Me</button>
</div>
</body>
...and here's the controller:
angular.module('angularApp', [])
.controller('firstCtrl', function($scope) {
$scope.helloWorld = function() {
console.log('You just pressed the button.');
};
$scope.project = {
completed :false,
title :'test',
};
});
The only thing that shows up in the label is '1+2='.
UPDATE: After spending a ridiculous amount of time trying to debug this I have been able to get the first value of the math expression to display -- the '1'. I achieved this by adding a space around the '+' operator. Still, the full expression is not evaluating.

If you're using another templating engine, such as Twig, Liquid, or Django, the curly braces may be being stripped out. This results in the values not displaying or evaluating properly.
The solution I found is editing the interpolation characters or $interpolateProvider like so inside your controller:
angular.module('angularApp', []).config(function($interpolateProvider){
$interpolateProvider.startSymbol('{[{').endSymbol('}]}');
})
Then, just wrap your expression in the new symbols, e.g.:
{[{ 1+2 }]}
...or
{[{ project.title }]}

I had the same issue and finally found it, simply open your web page and press f12 and view the console :) Also remove any unused css. Additionally make sure that you add the "ng-controller" in the tag or some other broad scope so its well covered within the scope.

Related

ng-keyup firing but not reading properly when used with an ng-if inside a directive template

I have a directive and it works fine in a way such that when I type something the search() scope function inside my directive fires and sets $scope.query with the input text.
here is the directive template
<div class="container">
<div class="system-filter-header">
<div class="no-gutter">
<div class="system-search-wrapper search-wrapper-width">
<i ng-click="search($evt)" class="fa fa-search"></i>
<input type="text" ng-keyup=search($evt) class="search pull-left suggesstions-styles"
ng-model="query" ng-attr-placeholder="Search...">
</div>
</div>
</div>
</div>
here is the scope function which gets triggered
$scope.search = function() {
console.log($scope.query.length)
}
But when I used an ng-if="true" in first line of template (true used for generalizing only, I want to do a different conditional check inside ng-if) such that,
<div class="container" ng-if="true">
still the search gets triggered but the console.log gives always 0 and it doesn't seem to update the $scope.query value as it stays as $scope.query = ''
throughout the typing.
EDIT
Here is a an example codepen with almost similar behaviour. The problem is with the searchBox directive and I have added ng-if=true to the template but searching doesn't work. When I remove the ng-if searching works fine.
Any reason for this?
Rule of thumb in AngularJS: your ng-model should always include a dot. Otherwise AngularJS directives that create child scopes (like ng-if or ng-repeat) will create a duplicate property on that child scope instead of the parent scope. Following the controllerAs convention completely mitigates this behavior.

TypeError: Cannot read property 'inputText' of undefined because of naming convention i used like "lunchCtrl.iform.inputText"

I am getting this error when i click the button without entering anything in input field. I am seeing this is because of the naming convention as "lunchCtrl.iform.inputText". when i use this as "lunchCtrl.inputText" or just "inputText" in controller and html its going good without error for empty value onbutton click.
if i enter any text and click the button its going good.
can anyone help me whats going wrong here.
i have attached the code in the following jsfiddle [here][1]. please help me to find the reason.
https://jsfiddle.net/29bmy95j/
code for here:
index.html
Lunch Checker
<div class="form-group">
<input id="lunch-menu" type="text"
placeholder="list comma separated dishes you usually have for lunch"
class="form-control" ng-model="lunchCtrl.iform.inputText">
</div>
<div class="form-group">
<button class="btn btn-default" ng-click="checkTooMuch()">Check If Too Much</button>
</div>
<div class="form-group message">
<!-- Your message can go here. -->
</div>
Entered values::{{lunchCtrl.iform.inputText}}
<p ng-bind="errorMsg" style="color:red"></p>
App.js:
var app=angular.module('LunchCheck', []);
app.controller('LunchCheckController', ["$scope",function($scope){
//function for checkTooMuch() ng-click event
$scope.checkTooMuch=function(){
var inputfieldVal=$scope.lunchCtrl.iform.inputText;
$scope.inputfieldValScope=inputfieldVal;
var array=inputfieldVal.split(',');
//$scope.array=array;
var arrLen=array.length;
if(arrLen > 3){$scope.errorMsg="Too much!";}
else{$scope.errorMsg="Enjoy!";}
}
}]);
error Image
Because $scope.lunchCtrl.iform is not defined, thus initially when you don't type anything in the textfield $scope.lunchCtrl.iform.inputText will trigger an error.
$scope.checkTooMuch=function(){
var inputfieldVal=$scope.lunchCtrl.iform.inputText;//error
So the fix would be to
OPTION 1
write a check and avoid:
$scope.checkTooMuch=function(){
if (!$scope.lunchCtrl.iform.inputText){
return;
}
...your code
OPTION 2
Define your variable like below in the controller
app.controller('LunchCheckController', ["$scope",function($scope){
//var v=$scope.inputText='';
this.iform = {inputText:""};
...
working code here

Struts2 <s:checkbox> with 'value="true" not rendered as preselect if has Angular `ng-model`

I have observed a very peculiar behavior of <s:checkbox> rendering along with Bootstrap 3 and AngularJS.
I have these two <s:checkbox> in my page, wrapped by some elements of Bootstrap 3 styles:
<div class="col-md-1">
<div class="form-group">
<div class="form-other">
<label for="activaCheck"><s:text name="actividad.busqueda.activa"/></label>
<s:checkbox class="form-control" id="activaCheck" name="activaCheck" ng-model="formData.activaCheck" value="true"></s:checkbox>
<s:checkbox class="form-control" id="activaCheck2" name="activaCheck2" value="true"></s:checkbox>
</div>
</div>
</div>
As you can see, the only difference between them, is that the first has attribute ng-model = "xxx", while the second doesn't.
And, in my page, they are rendered differently, although they both are supposed to be pre-selected, because I set value="true". And when we inspect in FF, we can see the first <s:checkbox> has checked="checked", but is not rendered. I have tested in Chrome and FF, same.
I have also tested with <input type="checkbox" /> with ng-model set and checked="checked", the same: not checked when rendered in page.
So I am thinking about AngularJS is taking over part of rendering job which Struts 2 is responsible of, at least in this case. I want some explanation from developers of AngularJS, or this is the expected result?
I got the problem with unchecked checkbox. Because it has ng-model attribute the input control is bound to Angular's $scope. And if the scope doesn't define the property value for the above named checkbox it's not checked. Assumed that AngularJS modifies DOM as soon as it initializes.
I have created plnkr to demonstrate it.
You are right AngularJS starts working after document is loaded. At this time Struts has already done its work and returned html document to the browser. Now Angular continues to prepare the page to work only on one page. Both complement each other, but if Struts use to render
<input type="checkbox" ng-model="checkboxModel.value1" checked="checked">
Angular removes the checked state, because the value is commented
angular.module('checkboxExample', [])
.controller('ExampleController', ['$scope', function($scope) {
$scope.checkboxModel = {
//value1 : true,
value2 : 'YES'
};
}]);

Set ons-switch with predifined values from Angular controller

I cannot seem to get the correct way to set the 'checked' attribute in ons-switch. This is so that I can setup user configurations page with pre-checked select boxes.
The Docs:
This is a checked switch but how do I set this using a variable in an angular controller?
For example, if ons-switch has a syntax like
I could have done:
I cannot seem to set attribute "checked" with no value in angular, as needed in the docs. I'm also unable to access the variable since it is part of an array of configurations.
Code Example:
controller:
var categInfo = [{Interest:'Classic', isChecked:true}, {Interest:'New', isChecked:false}];
html:
<ons-list-item ng-repeat="interest in categInfo" >
<span style="color: #666">{{interest.Interest}}</span>
<ons-switch modifier="list-item" var="{{interest.Interest}}" checked="{{interest.isChecked}}"></ons-switch>
</ons-list-item>
So what I want is that the html should show buttons that are checked/unchecked depending on interest.isChecked is true or false.
First of all, you need to bind the switch with ng-model, this will allow you to manage the ons-switch behavior directly from the controller. Setting the variable true or false, inside the controller, will automatically change the value of the state of the switch, same thing if you change the state from the switch (AngularJS binding).
If you want to check the status of the switch, you need to check the model value.
Here is a CodePen example. and the relative code.
HTML
<div ng-controller="MyController">
<ons-switch ng-model="switch"></ons-switch>
<ons-button ng-click="changeSwitch()">Change switch status</ons-button>
</div>
Controller
ons.bootstrap()
.controller('MyController', function ($scope) {
$scope.changeSwitch = function() {
$scope.switch = !$scope.switch;
if($scope.switch)
alert('checked');
else
alert('unchecked');
};
});
EDIT: SWITCH ARRAY EXAMPLE
Due to an Onsen UI bug about the initialization of the ons-switch element, I suggest you to use the following code to implement your switch.
<label class="switch">
<input type="checkbox" class="switch__input" checked>
<div class="switch__toggle"></div>
</label>
The appearance will be the same as the ons-switch element. This bug will be fixed in Onsen UI 1.4 release, so you can start using again the switch element after its release.
For what concerns the behavior of an array of switches, it's analog of the single switch. You still need to use 'ng-model' to bind the status of the switch. You are using ng-repeat to display the switch elements so, by using ng-model="item.isChecked", every element will be binded with the relative isChecked value inside the array. Here you can find a working CodePen example, and this is the relative code:
HTML
<div ng-controller="MyController">
<h2>What I am trying</h2>
<div ng-repeat="item in categInfo">
<div>This button should be {{item.isChecked}}</div>
<label class="switch">
<input ng-model="item.isChecked" type="checkbox" class="switch__input" checked>
<div class="switch__toggle"></div>
</label>
</div>
</div>
Controller
ons.bootstrap()
.controller('MyController', function ($scope, $timeout) {
//Need to go through the array and set as checked or not
$scope.categInfo = [{Interest:'Classic', isChecked:true}, {Interest:'New', isChecked:false}];
});

AngularJS's ng-model icm textarea

I'm trying to add some text to the last cursor place after clicking a button.
In the controller:
$scope.addEmoji = function(name){
var element = $("#chat-msg-input-field");
element.focus(); //ie
var selection = element.getSelection();
var textBefore = $scope.chatMsg.substr(0, selection.start);
var textAfter = $scope.chatMsg.substr(selection.end);
$scope.chatMsg = textBefore + name + textAfter;
}
$scope.updateChatMsg = function(chatMsg){
$scope.chatMsg = chatMsg;
}
$scope.sendChatMsg = function(){
var backend = $scope.convs[$scope.active.conv].backend.name;
$scope.view.addChatMsg($scope.active.conv, $scope.active.user, $scope.chatMsg,new Date().getTime() / 1000, backend);
Chat[backend].on.sendChatMsg($scope.active.conv, $scope.chatMsg);
$scope.chatMsg = '';
};
And then some HTML:
<div class="chat-msg-button" >
<button ng-click="view.toggle('emojiContainer')" ><img src="/apps/chat/img/emoji/smile.png"></button>
</div>
<form id="chat-msg-form" ng-submit="sendChatMsg()">
<div class="chat-msg-button" >
<button type="submit"><div class="icon-play"> </div></button>
</div>
<div id="chat-msg-input">
<textarea id="chat-msg-input-field" autocomplete="off" type="text" ng-model="chatMsg" ng-change="updateChatMsg(chatMsg)" placeholder="Chat message"></textarea>
<div>{{ chatMsg }}</div>
</div>
</form>
What I'm trying to achieve: a user types some text in the textarea => $scope.chatMsg gets the value of the textarea. Now the user press one of the button's => the name of the button is added to the latest cursor position. (it's no problem to find the latest cursor position)
The problem
There is a difference between the value of $scope.chatMsg, {{ chatMsg }} inside the div and the text in the textarea.
The contents of the textarea and the div stays always the same. But when pressing the button the name is added to $scope.chatMsg but the contents of the textarea isn't changed...
How can I solve this?
TIA
First of all, you're mixing jQuery with AngularJS, it doesn't look like you need jQuery here that much.
Also, your chat message is updated in 3 different functions, so you need some debugging to see which are fired.
In general:
To solve your issue, try some more debugging, do a
$scope.$watch($scope.chatMsg, function(){
console.log($scope.chatMsg);
});
this will watch all changes to chatMsg. Add console.log() to each of your functions and you can watch which is fired.
Also, rather than using {{ }} inside your div just use ng-bind since that text is the only item in your div, it's cleaner if your app crashes somewhere.
// change from
<div>{{ chatMsg }}</div>
// to
<div ng-bind="chatMsg "></div>
Update: after seeing your plunker, I modified it and came up with this: http://plnkr.co/edit/oNKGxRrcweiJafKCm9A5?p=preview
Your ng-repeat needs to be tracked by $index so that duplicates are displayed rather than crashing when someone creates the same message
I solved all problems. The plunkr form above works. So after investigating all scopes with the Angular chrome extension I saw that chatMsg was defined in another scope. Thus not in the scope I was trying to acces it from.
Via this question angularJS ng-model input type number to rootScope not updating I found a solution.
I added chatMsg to the fields object.

Resources