Weird Angular Binding Issue - angularjs

I'm having a weird angularjs binding problem
<a class="navbar-brand" href="#">Application (Environment: {{ globalConfig.environment + ""}})</a>
That will work, and render the value "dev"
<a class="navbar-brand" href="#">Application (Environment: {{ globalConfig.environment }})</a>
This doesn't render anything.
<a class="navbar-brand" href="#">Application (Environment: <span ng-bind="globalConfig.environment"></span>)</a>
This last example works.
Any ideas why the second example won't render out the value "dev"?
The controller is as follows:
angular.module('uppApp').controller('globalController', function ($scope) {
$scope.globalConfig = {
environment: 'dev'
};
});
the html looks as follows:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" ng-app="uppApp">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<meta name="author" content="">
<link rel="icon" href="../../favicon.ico">
<title>Pixel Pimp Web UI</title>
<link href="assets/css/style.css" rel="stylesheet" />
<!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!--[if lt IE 9]>
<script src="assets/thirdparty/ie8mediasupport.js"></script>
<![endif]-->
</head>
<body ng-controller="globalController">
<div class="navbar navbar-fixed-top" role="navigation">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">Pixel Pimp (Environment: <span ng-bind="globalConfig.environment"></span>)</a>
</div>
<div class="collapse navbar-collapse">
<ul class="nav navbar-nav">
<li class="active">Dashboard</li>
<li>Pixel Groups</li>
</ul>
</div><!--/.nav-collapse -->
</div>
</div>
<div class="container">
<h1>Dashboard</h1>
<div id="myfirstchart" style="height: 250px;"></div>
</div><!-- /.container -->
<script src="assets/thirdparty/built.js"></script>
<script src="assets/js/uppangular.js"></script>
<script>
$(function () { genGraph(); });
function genGraph() {
new Morris.Line({
// ID of the element in which to draw the chart.
element: 'myfirstchart',
// Chart data records -- each entry in this array corresponds to a point on
// the chart.
data: [
{ year: '2008', value: 20 },
{ year: '2009', value: 10 },
{ year: '2010', value: 5 },
{ year: '2011', value: 5 },
{ year: '2012', value: 20 }
],
// The name of the data record attribute that contains x-values.
xkey: 'year',
// A list of names of data record attributes that contain y-values.
ykeys: ['value'],
// Labels for the ykeys -- will be displayed when you hover over the
// chart.
labels: ['Value']
});
}
</script>
</body>
</html>
UPDATE
When i wrap the decorate the interpolate service for debugging like this:
app.config(function($provide){
$provide.decorator("$interpolate", function($delegate){
var interpolateWrap = function(){
var interpolationFn = $delegate.apply(this, arguments);
if(interpolationFn) {
return interpolationFnWrap(interpolationFn, arguments);
}
};
var interpolationFnWrap = function(interpolationFn, interpolationArgs){
return function(){
var result = interpolationFn.apply(this, arguments);
var log = result ? console.log : console.warn;
log.call(console, "interpolation of " + interpolationArgs[0].trim(),
":", result.trim());
return result;
};
};
angular.extend(interpolateWrap, $delegate);
return interpolateWrap;
});
});
The console log will show:
interpolation of {{globalConfig.environment+""}} : dev
However for the binding of {{globalConfig.environment}} nothing shows up in the console window.

Ok I figured it out. I'm using grunt bake for the first time, and I think grunt bake, is stripping out the {{globalConfig.environment}} code from the rendered file.
Sorry. Stupid mistake.
UPDATE
Ultimately I fixed it by modifying the BAKE parse pattern to use [{ }] instead of {{ }}
bake: {
build: {
options: {
parsePattern: '/\[\{\s?([\.\-\w]*)\s?\}\]/g'
},
files: {
"app/index.html": "app/base.html"
}
}
},

Related

Angularjs Model Array Not updating with Template

I've created the template with the below code. The edit functionality works fine however the model is updating back.
In the template, I've binded the model with ng-model but still it is not updating the model hobbies back on editing
Any ideas?
<html>
<head>
<title>
Angular Edit Template
</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.0/css/bootstrap.min.css" integrity="sha384-PmY9l28YgO4JwMKbTvgaS7XNZJ30MK9FAZjjzXtlqyZCqBY6X6bXIkM++IkyinN+" crossorigin="anonymous">
<script type="text/javascript" language="javascript" src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
<script type="text/javascript" language="javascript" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.7/angular.js"></script><!-- Latest compiled and minified CSS -->
<script src="https://stackpath.bootstrapcdn.com/bootstrap/3.4.0/js/bootstrap.min.js" integrity="sha384-vhJnz1OVIdLktyixHY4Uk3OHEwdQqPppqYR8+5mjsauETgLOcEynD9oPHhhz18Nw" crossorigin="anonymous"></script>
<script type="text/javascript">
angular.module('myApp', [])
.controller('myCtrl', function($scope){
$scope.hobbies = ["Swimming", "Reading"]
})
.directive('component', function(){
return {
template: [
'<div>',
'<span ng-show="!editing">{{ value }} <i ng-click="editing = true" class="glyphicon glyphicon-pencil"></i></span>',
'<span ng-show="editing"><input type="input" ng-model="value"><i ng-click="editing = false" class="glyphicon glyphicon-ok"></i></span>',
'</div>'
].join(''),
restrict: 'E',
scope: {
value: '=value'
},
link: function($scope){
$scope.editing = false;
}
}
});
</script>
</head>
<body>
<div id="test" ng-app="myApp" ng-controller="myCtrl">
<ul ng-repeat="n in hobbies">
<li>
<component value="n"></component>
</li>
</ul>
<span>{{ hobbies }}</span>
</div>
</body>
</html>
Take a look at this, the issue is you're two way binding a string, instead of an object, which means you're not actually getting the benefits: If you are not using a .(dot) in your AngularJS models you are doing it wrong?
If you use an object in either your parent, either passing the value or the whole object, you'll see that it works a little better.
$scope.hobbies = [{id:1,name:"Swimming"},{id:2,name:"Reading"}]
and then
<ul ng-repeat="n in hobbies">
<li>
<component value="n.name"></component>
</li>
</ul>
or
'<span ng-show="!editing">{{ value.name }} <i ng-click="editing = true" class="glyphicon glyphicon-pencil"></i></span>',
'<span ng-show="editing"><input type="input" ng-model="value.name"><i ng-click="editing = false" class="glyphicon glyphicon-ok"></i></span>',

create html elements in a factory in angular.js

I have a css that helps me to generate a preloader or a loading animation. The only thing I lack is the html code. My idea is to create a factory that allows to create the html code necessary for the preloader to be generated. Can you please give me an example or say how to do it ?.
thank you very much.
This can be effectively achieved using AngularJS 1.5's Components
The code creates a <menu-bar> component which spits out bootstrap <nav-bar> in the template.
//-- app.module.js --//
var app = angular.module('app', []);
//-- app.menu-bar.component.js --//
app.component('menuBar', {
bindings: {
brand: '#'
},
templateUrl: '/partials/menuBar.html',
controller: function() {
this.menu = [{
name: "Home",
}, {
name: "About",
}, {
name: "Contact",
}];
}
});
<!-- /partials/menuBar.html -->
<nav class="navbar navbar-default">
<div class="container">
<div class="navbar-header">
<a class="navbar-brand" href="#">{{$ctrl.brand}}</a>
</div>
<div>
<ul class="nav navbar-nav">
<li ng-repeat="menu in $ctrl.menu">
<a href="#">{{menu.name}}
</a>
</li>
</ul>
</div>
</div>
</nav>
<!-- End of menuBar.html -->
<!-- index.html -->
<html en="us" ng-app='app'>
<head>
<title>
NavBar with Angular 1.5.x components
</title>
<!-- bootsrap css-->
<link rel="stylesheet" type="text/css" href="lib/bootstrap/dist/css/bootstrap.min.css">
<!-- angularjs-->
<script src="lib/angular/angular.min.js"></script>
<!-- The main app script-->
<script src="js/app.module.js"></script>
<script src="js/components/app.navbar.component.js"></script>
</head>
<body>
<menu-bar brand='abc'></menu-bar>
</body>
</html>

Cannot click button inside a list (ng-repeat)

I'm having a problem with a button inside a list. The list is being built with ng-repeat. I'm trying to create a simple web app for creating tasks. Given the following code,
I can't click the button which is supposed to show the task description (the one with the gear). Thank you in advance.
HTML:
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
<title>Tasks List</title>
<link rel="manifest" href="manifest.json">
<!-- un-comment this code to enable service worker
<script>
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('service-worker.js')
.then(() => console.log('service worker installed'))
.catch(err => console.log('Error', err));
}
</script>-->
<link href="lib/ionic/css/ionic.css" rel="stylesheet">
<link href="css/style.css" rel="stylesheet">
<!-- IF using Sass (run gulp sass first), then uncomment below and remove the CSS includes above
<link href="css/ionic.app.css" rel="stylesheet">
-->
<!-- ionic/angularjs js -->
<script src="lib/ionic/js/ionic.bundle.js"></script>
<!-- cordova script (this will be a 404 during development) -->
<script src="cordova.js"></script>
<!-- your app's js -->
<script src="js/app.js"></script>
</head>
<body ng-app="todo" ng-controller='mainCtrl'>
<ion-pane>
<ion-header-bar class="bar-dark">
<h1 class="title">Tasks</h1>
</ion-header-bar>
<ion-content>
<div class="list list-inset">
<label class="item item-input">
<input type="text" name="list" placeholder="Task Name" ng-model="task">
</label>
<label class="item item-input">
<input type="text" placeholder="Description" ng-model="description">
</label>
</div>
<button class ="button button-dark right" ng-click="add(task,description)">Add</button>
<div class="row">
<div class="col"></div>
<div class="col"></div>
<div class="col col-50">
<ion-list show-delete="1==1" ng-repeat="task in tasks">
<ion-item>
{{task.taskname}}
<ion-delete-button class="ion-minus-circled" ng-click="delete(task)"></ion-delete-button>
<button ng-click="task.selected=!task.selected" class="btn button icon ion-gear-a"></button>
</ion-item>
<div class="item item-divider" ng-show="task.selected">
{{task.description}}
</div>
</ion-list>
</div>
</div>
</ion-content>
</ion-pane>
</body>
</html>
app.js:
angular.module('todo', ['ionic'])
.controller('mainCtrl',function($scope, $ionicModal){
$scope.tasks=[
{
taskname: 'Hi',
description:'I am a description',
selected: false
},
{
taskname:'Hello',
description:'I am another description',
selected: false
},
{
taskname: '123',
description:'I am another description',
selected: false
},
{
taskname: '456',
description:'I am another description',
selected: false
},
{
taskname: '789',
description:'I am another description',
selected: false
},
]
$scope.select=-1;
$scope.add=function(task,description){
if ($scope.tasks.indexOf(task)!== -1){
this.list="Already exists!"
}
else{
newtask={
taskname: task,
description: description,
selected: false
};
$scope.tasks.push(newtask);
}
};
$scope.delete=function(task){
var index = $scope.tasks.indexOf(task);
$scope.tasks.splice(index, 1);
}
});
Your controller line should be:
.controller('mainCtrl', ['$scope', '$ionicModal', function($scope, $ionicModal) {
And obviously the extra ] at the end.
I removed the ios-list and ion-item tags and replace them with the ul and li ones and it worked perfectly, is there something wrong with those tags?

AngularJs routing issue 404

I am completely new to the AngularJS, trying to learn MVC with AngularJS, sort of mini SPA. For some reason the AngularJS routing is not working for me. I have tried so many combinations, non of them worked. Any clues what I might have wrong? The error I receive is 'The resource cannot be found' 404 when clicked on the button with a link that MVC does not have view method implemented for. It seems like MVC routing is being processed before angularJs client side routing is:
Layout:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>#ViewBag.Title - My ASP.NET Application</title>
<link href="~/Content/Site.css" rel="stylesheet" type="text/css" />
<link href="~/Content/bootstrap.min.css" rel="stylesheet" type="text/css" />
<script src="~/Scripts/modernizr-2.6.2.js"></script>
<link href="~/Content/bootstrap-superhero.css" rel="stylesheet" />
<script src="~/Scripts/angular.js"></script>
<script src="~/Scripts/angular-resource.js"></script>
<script src="~/Scripts/angular-route.js"></script>
<script src="~/Scripts/registration-module.js"></script>
#RenderSection("head", false)
</head>
<body>
<div class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
#Html.ActionLink("Application name xxx", "Index", "Home", new { area = "" }, new { #class = "navbar-brand" })
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
</ul>
</div>
</div>
</div>
<div class="container body-content" ng-app="registrationModule">
#RenderBody()
<hr />
<footer>
<p>© #DateTime.Now.Year - My ASP.NET Application</p></footer>
</div>
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script src="~/Scripts/bootstrap.min.js"></script>
</body>
</html>
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Registration", action = "Index", id = UrlParameter.Optional }
);
//routes.MapRoute(
// name: "Application",
// url: "{*url}",
// defaults: new { controller = "Registration", action = "Index" });
}
}
Angular registration:
var registrationModule = angular.module("registrationModule", ['ngRoute','ngResource'])
.config(function ($routeProvider, $locationProvider) {
//$routeProvider.when('/Registration/Courses', { templateUrl: '/Templates/courses.html', controller: 'CoursesController' });
$routeProvider.when('/Registration/Courses', { templateUrl: '/Templates/test.html' });
$routeProvider.when('/Registration/Instructors', { templateUrl: '/Templates/instructors.html', controller: 'InstructorsController' });
$routeProvider.otherwise({ redirectTo: '/' });
$locationProvider.html5Mode(true);
});
View
#model Ang2.Models.Registration.Registration
#{
ViewBag.Title = "Index";
}
<div class="container">
<div class="row">
<div class="navbar navbar-default">
<div class="navbar-header">
<ul class="nav navbar-brand">
<li><span class="navbar-brand"></span></li>
</ul>
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li>Browse Catalog</li>
<li>Browse Instructors</li>
</ul>
</div>
</div>
</div>
<div ng-view></div>
</div>
Physical files exist:
It seems you are using HTML5 routing mode html5Mode(true), but have not specified the base url, so that angular knows where to start the routing. You could try either disable the HTML5 mode (set it to false), or specify the base using <base> tag.
Note that server-side (C# code) is completely unrelated and not used for client-side routing. Also note that you should not expect your controllers to be called, because angular routing is a client-side only, it does not call the server by itself. Means, "view" will NOT be processed by c#, you will just get plain html.
All in all, it looks you don't need angular routing at all, since you seem to be doing routing server side.

values not getting displayed using angular directive

I am trying to add directive in angular and use the same to display the values. However the values are not getting displayed.
My html code
<!doctype html>
<html>
<head>
<link href="https://s3.amazonaws.com/codecademy-content/projects/bootstrap.min.css" rel="stylesheet" />
<link href='https://fonts.googleapis.com/css?family=Playfair+Display:400,400italic,700italic|Oswald' rel='stylesheet' type='text/css'>
<link href="css/main.css" rel="stylesheet" />
<script src="js/vendor/angular.min.js"></script>
</head>
<body ng-app="PizzaPlanetApp">
<div class="header" >
<h1><span>Pizza</span><span>Planet</span></h1>
</div>
<div class="main" ng-controller="MainController">
<div class="container">
<h1>Specials for {{ today | date }}</h1>
<h2>Appetizers</h2>
<div ng-repeat="appetizer in appetizers">
<div class="item col-md-9">
<pizza-info info=appetizer> </pizza-info>
</div>
</div>
</div>
</div>
<!-- Modules -->
<script src="js/app.js"></script>
<!-- Controllers -->
<script src="js/controllers/MainController.js"></script>
<!--directives-->
<script src="js/directives/pizzaInfo.js"></script>
</body>
</html>
Controller
app.controller('MainController', ['$scope', function($scope) {
$scope.today = new Date();
$scope.appetizers = [
{
name: 'Caprese',
description: 'Mozzarella, tomatoes, basil, balsmaic glaze.',
price: 4.95
},
{
name: 'Mozzarella Sticks',
description: 'Served with marinara sauce.',
price: 3.95
},
{
name: 'Bruschetta',
description: 'Grilled bread garlic, tomatoes, olive oil.',
price: 4.95
}
];
}]);
Directive(pizzaInfo.js)
app.directive('pizzaInfo', function(){
return {
restirct:'E',
scope:{
info:'='
},
templateUrl: 'js/directives/pizzaInfo.html'
};
});
Directive html(pizzaInfo.html)
<h3 >{{info.name}} </h3>
<p > {{info.description}}</p>
<p >{{info.price | currency}} </p>
I am not getting any error in the console.log. What is that i am missing here?
Syntax Error :))
app.directive('pizzaInfo', function(){
return {
/****/restrict:'E',
scope:{
info:'='
},
templateUrl: 'js/directives/pizzaInfo.html'
};
});

Resources