Right I've got a really dumb one for you, and I've been looking at this code all day with no result.
I have a simple textbox which goes through a controller and updates a variable inside a service (The service will eventually fetch/update data from somewhere else).
At the moment, I am able to retrieve the variable value all the way to the view and it works, but the textbox is unable to update the variable inside the service in order to then display the new variable value in the view again....
I really appreciate any help and hope I have made sense!!!
// APP/APP.JS
(function(){
var app = angular.module('appMod', ['ngRoute', 'ngAnimate']);
app.config(function ($routeProvider) {
$routeProvider
.when('/',
{
controller: 'introController',
templateUrl: 'app/partials/intro.html'
})
.otherwise({ redirectTo: '/' });
});
app.controller('nameController', function($scope, dataService) {
var nameValue;
this.name = dataService.getName();
this.submitName = function(nameVal) {
nameValue = this.nameCtrl.nameVal;
dataService.setName(nameValue);
};
});
app.controller('introController', function($scope, dataService) {
this.name = dataService.getName();
});
app.service('dataService', function () {
var name = "f";
this.getName = function() {
return name;
};
this.setName = function(nameVal) {
name = nameVal;
};
});
})();
<!-- INDEX.HTML -->
<!DOCTYPE html>
<html ng-app="appMod">
<head>
<link rel="stylesheet" type="text/css" href="content/css/normalize.css">
<link rel="stylesheet" type="text/css" href="content/css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="content/css/style.css">
<link rel="stylesheet" type="text/css" href="content/css/animation.css">
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<script type="text/javascript" src="scripts/bootstrap.min.js"></script>
<script type="text/javascript" src="scripts/angular.min.js"></script>
<script type="text/javascript" src="scripts/angular-route.min.js"></script>
<script type="text/javascript" src="scripts/angular-timer.min.js"></script>
<script type="text/javascript" src="scripts/angular-animate.min.js"></script>
<script type="text/javascript" src="app/app.js"></script>
</head>
<body>
<div class="container">
<div class="row" ng-controller="nameController as nameCtrl">
<img src="content/images/sitelogo.png" class="logo">
<h2 class="welcomeMessage fade">Welcome <span class="fade" ng-show="!nameCtrl.name == ''">{{nameCtrl.name}}</span><span class="inline fade" ng-hide="nameCtrl.name !== ''">Friend</span> <small>(We like to get personal!)</small></h2>
<div class="namebox fade">
<h2>Welcome <small class="fade">Please type your name</small></h2>
<form class="fade">
<div class="form-group">
<input type="text" class="form-control" ng-model="nameCtrl.nameVal" autofocus>
</div>
<button type="submit" style="width:100%;" class="btn btn-default fade" ng-click="nameCtrl.submitName()" >Submit</button>
</form>
</div>
</div>
</div>
<div ng-view></div>
</body>
</html>
You need to be binding to name and not nameVal on your input
Then just pass that in your setName call, i don't think the rest of the code is needed in there, you can get rid of the nameValue var too.
this.submitName = function() {
dataService.setName(this.name);
};
The nameValue var is local to the controller and not available on the $scope to bind to your view, so even though you were changing it, the view didn't know about it as it couldn't see that var.
Related
I am learning angularjs and bootstrap.
It is simple, but I dont know, what I am doing wrong.
The point is to reload the page with a button, but I was not able to get inside the function, which has to reload the page.
This is my component.js
myApp.component('refreshComponent', {
template:"<button class='btn btn-lg btn-info' ng-click='refresh()' >Refresh </button>",
controller: function RefreshController($scope, $element, $attrs) {
var vm = this;
vm.refresh = function(){
console.log("How to get here?")
location.reload();
}
}
});
This is my index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"
integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<!-- Optional theme -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css"
integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
</head>
<body>
<div ng-app="myApp" class="container bg-primary img-rounded">
<h1>
<div class="row">
<div class="col-xs-6 text-right">
<date-component></date-component>
</div>
</div>
<div class="row">
<div class="col-xs-6 text-right">
<greetings-component></greetings-component>
</div>
</div>
<div class="row">
<div class="col-xs-6 text-right ">
<refresh-component></refresh-component>
</div>
</div>
</h1>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.7.9/angular.min.js"></script>
<script src="date.component.js"></script>
<script src="greetings.component.js"></script>
<script src="refresh.component.js"></script>
</body>
</html>
BTW those other componnent are working
var myApp = angular.module('myApp', []);
myApp is initialized in date.component.js
Be sure you added controllerAs: 'vm', to your component and ng-click='refresh() to ng-click='vm.refresh()
So your component should look like:
myApp.component('refreshComponent', {
template:"<button class='btn btn-lg btn-info' ng-click='vm.refresh()' >Refresh </button>",
controllerAs: 'vm',
controller: function RefreshController($scope, $element, $attrs) {
var vm = this;
vm.refresh = function(){
console.log("How to get here?")
location.reload();
}
}
});
Tip 1:
if you use vm, you don't need $scope at all. A.e.:
function RefreshController($element, $attrs)
Tip 2:
If you go to obfuscate your code, worth to use $inject to avoid unexpected behavior:
myApp.component('refreshComponent', {
template:"<button class='btn btn-lg btn-info' ng-click='vm.refresh()' >Refresh </button>",
controllerAs: 'vm',
controller: RefreshController
});
function RefreshController($element, $attrs) {
var vm = this;
vm.refresh = function(){
console.log("How to get here?")
location.reload();
}
}
RefreshController.$inject = ['$element', '$attrs'];
Here is the code in concern:
<div ng-app="">
https://www.facebook.com/sharer/sharer.php?u={{$location.absUrl()}}
https://www.facebook.com/sharer/sharer.php?u={{$location.$$url}}
https://www.facebook.com/sharer/sharer.php?u={{$location.$$path}}
</div>
We need the value of the u parameter to be current page.
Where are we wrong?
You cannot do that in HTML, alternatively you can get the current location like this,
Assign the curren location to a scope variable,
$scope.a = window.location.href;
Then in HTML,
<br>Link = <a ng-href="https://www.facebook.com/sharer/sharer.php?u={{a }}" target="_blank">facebook</a>
DEMO
<!DOCTYPE html>
<html>
<head>
<script data-require="angular.js#*" data-semver="1.3.0-beta.5" src="https://code.angularjs.org/1.3.0-beta.5/angular.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
<script type="text/javascript">
var myApp = angular.module('myApp', []);
myApp.controller('TestCtrl', ['$scope', function($scope) {
$scope.a = window.location.href;
}]);
</script>
</head>
<body ng-app="myApp">
<div ng-controller="TestCtrl">
<input type="text" ng-model="a">
<br>a={{a}}
<br>
<br>Link = <a ng-href="https://www.facebook.com/sharer/sharer.php?u={{a}}" target="_blank">facebook</a>
</div>
</body>
</html>
The property which are present of $scope variable those are only available to use on HTML as binding. So $location service you have to expose on $scope
//inject $location to controller before use it.
$scope.$location = $location;
I am creating a small web app where I will show a chart of the top 10 popular TV shows. Then, When I go to the browser and inspect I get an error:
Error: [$injector:unpr] http://errors.angularjs.org/1.5.6/$injector/unpr?p0=showProvider%20%3C-%20show%20%3C-%20MainController
<!doctype html>
<html>
<head>
<link href='https://fonts.googleapis.com/css?family=Montserrat:400,700' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<link href="css/main.css" rel="stylesheet" />
<!-- Angular JS -->
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
<body ng-app="Top10App">
<div class="header">
<div class="container">
10
</div>
</div>
<div class="main" ng-controller="MainController">
<div class="container">
<div class="content">
<!--TODO: Loop through shows and display each one with this HTML-->
<!--ng-repeat="show in shows" -->
<div>
<div class="rank">{{$index + 1}}</div>
<h2 class="series"> {{ index.series }}</h2>
<p class="genre">{{ index.genre }} </p>
<p class="run-start"> {{ index.run_start }}</p>
<p class="description"> {{ index.description }} </p>
</div>
</div>
</div>
</div>
<!-- Modules -->
<script src="js/app.js"></script>
<!-- Controllers -->
<script src="js/controllers/MainController.js"></script>
<!-- Services -->
<script src="js/services/show.js"></script>
</body>
</html>
Javascript
MainController.js
app.controller('MainController', ['$scope', 'show', function ($scope, show) {
show.success(function(data) {
$scope.show = data;
});
}]);
show.js
app.factory('Top10App', ['$http', function($http){
return $http.get('shows.json')
.success(function(data){
return data;
})
.error(function(err){
return err;
});
}]);
You're defining your service name as 'Top10App', so that's the way you should access it, not by the file name.
['$scope', 'Top10App', function ($scope, Top10App) { ...
Top10App.success(...
First, do you created the module? You should has something like:
// app.js
angular.module('app', []);
// maincontroller.js
angular.module('app').controller('myController, ...', [.......]);
// factory.js
angular.module('app').factory(...)
You are trying to inject show as a dependency for your controller, but it doesn't look like that is defined anywhere. That's why your error is telling you that it's an unknown provider.
I'm guessing you're trying to use your Top10App factory, so you need to inject it as such
app.controller('MainController', ['$scope', 'Top10App', function ($scope, Top10App) {
Top10App.success(...)
}
I want to have particular variable for menu to know which class to be active. Up to now I know how to set variable inside ng-view but I want to keep my menu out of that view. If I set variable in function in controller isn't visible outside of ng-view and that is exactly what I want to, to be visible. I try with rootscoope but I couldn't manage. If someone can help me my code is like this:
index.html
<!DOCTYPE html>
<html lang="en" ng-app="example">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="libs/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="assets/css/font-awesome.min.css" rel="stylesheet">
<link href="assets/css/main.css" rel="stylesheet">
<title>Example</title>
</head>
<body>
<div class="container-fluid main-header">
<div class="main-menu-active">First page</div>
<div class="main-menu">Second page</div>
</div>
<div ng-view class="main-body"></div>
<script src="libs/jquery/dist/jquery.min.js"></script>
<script src="libs/bootstrap/dist/js/bootstrap.min.js"></script>
<script src="libs/angular/angular.min.js"></script>
<script src="libs/angular-route/angular-route.min.js"></script>
<link href="libs/ng-dialog/css/ngDialog.min.css" rel="stylesheet">
<link href="libs/ng-dialog/css/ngDialog-theme-default.css" rel="stylesheet">
<script src="libs/ng-dialog/js/ngDialog.js"></script>
<script src="app/app.js"></script>
<script src="app/controllers/mainCtr.js"></script>
</body>
</html>
app.js
(function () {
'use strict';
angular
.module('example', ['ngRoute','ngDialog'])
.config(function ($routeProvider,$httpProvider) {
$routeProvider.when('/', {
controller: 'mainCtr',
controllerAs: 'mCtr',
templateUrl: 'app/views/firstPage.html'
});
$routeProvider.when('/second', {
controller: 'mainCtr',
controllerAs: 'mCtr',
templateUrl: 'app/views/secondPage.html'
});
$httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=utf-8';
}).run(function($http, $httpParamSerializerJQLike) {
//decode json on every submit form
$http.defaults.transformRequest.unshift($httpParamSerializerJQLike);
})
})();
controller:
(function() {
'use strict';
angular
.module('example')
.controller('mainCtr', mainCtr);
mainCtr.$inject = ['$window','$routeParams','ngDialog','$timeout'];
function mainCtr($window,$routeParams,ngDialog,$timeout) {
var vm = this;
vm.firstPage = firstPage;
vm.secondPage = secondPage;
function firstPage() {
vm.test = 'This is first page';
}
function secondPage() {
vm.test = 'This is second page';
}
}
})();
I want to have access to variable vm.test in <div class="container-fluid main-header">
I would make a Controller around the ng-view which hold the value(s):
<body ng-controller="OuterController">
<div class="container-fluid main-header">
<div class="main-menu-active">First page</div>
<div class="main-menu">Second page</div>
</div>
<div ng-view class="main-body"></div>
...
</body>
and if you want to share data between the controllers in ng-view directive use a service.
So I've made a plunker to illustrate, how data sharing is accomplished: https://plnkr.co/edit/axekEgrFwnm93aFXoMKd
So the basic idea is to use a service and in someway either by button click as in the question or automatically in contoller as plunker, set the shared value.
Service
app.service('commonInfomation', function() {
return {
test: ''
};
});
Inner controller
app.controller('FirstCtrl', function($scope, commonInfomation) {
commonInfomation.test = "Hello from first page";
});
Outer controller
app.controller('MainCtrl', function($scope, commonInfomation) {
$scope.commonInfomation = commonInfomation;
});
View
<body ng-controller="MainCtrl">
<h2>{{commonInfomation.test}}</h2>
<div class="container-fluid main-header">
<a href="#/">
<div class="main-menu-active">First page</div>
</a>
<a href="#/second">
<div class="main-menu">Second page</div>
</a>
</div>
<div ng-view class="main-body"></div>
</body>
Module
var app = angular.module('plunker', ['ngRoute']);
app.config(function($routeProvider) {
$routeProvider.when('/', {
templateUrl: 'firstpage.html',
controller: 'FirstCtrl'
})
.when('/second', {
templateUrl: 'secondpage.html',
controller: 'SecondCtrl'
})
});
I just want to test opening a left modal with the help of ngAside used at the following Repository:
https://github.com/dbtek/angular-aside
I think I am doing it right, still can find a js error. Can someone help?
index.html:
<html>
<head>
<!-- Required CSS -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.min.css"/>
<!-- Required Scripts -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.8/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/1.1.2/ui-bootstrap-tpls.min.js"></script>
<script src="../js/angular-aside.min.js"></script>
</head>
<body ng-app="myApp" ng-controller="myCtrl">
<input type="text" ng-model="name"/>
{{name}}
<script>
//module declaration
var app = angular.module('myApp',['ui.bootstrap', 'ngAside']);
//Controller declaration
app.controller('myCtrl',function($scope){
$scope.name = "Peter";
var asideInstance = $aside.open({
templateUrl: 'aside.html',
controller: 'AsideCtrl',
placement: 'left',
size: 'lg'
});
});
app.controller('AsideCtrl',function($scope){
});
</script>
</body>
</html>
aside.html
Hello World!
ERROR:
To use the aside service, you have to inject it like this (notice the $aside injection in the constructor) :
app.controller('myCtrl',function($scope, $aside){
...
});