connection between controller and view in angularjs - javascript

I have a problem with my AngularJS script with MVC architecture.
I think these errors are due to the incorrect connection between model, view and controller layers.
JS:
var myApp = angular.module("myApp", []); //App.js
myApp.controller('MainController', ['$scope', function MainController($scope) {
$scoope.title = "top sellers in books";
}]);
//MainController.js
HTML:
<!DOCTYPE html>
<html>
<head>
<title>Angular Js</title>
<link rel="stylesheet" type="text/css" href="bootstrap.min.css">
<script src="js/angular.js"></script>
</head>
<body ng-app="myApp">
<div class="header">
<div class="container">
<h1>book end</h1>
</div>
</div>
<div class="Main" ng-controller="MainController">
<div class="container" ng-model="title">
<h1>{{ title }}</h1>
</div>
</div>
<div class="footer">
<div class="container">
<h2>Available for iphone and android</h2>
<img src="http://lorempixel.com/400/200/">
<img src="http://lorempixel.com/400/200/">
</div>
</div>
<script src="js/Controller/MainController.js"></script>
<script src="js/App.js"></script>
</body>
</html>
Code Result
I receive the following errors in my browser console that say app variable is not defined and [ng:areq] Argument 'MainController' is not a function.
Errors:

I just edited my answer with the full correct code of the files that had errors:
index.html
<!DOCTYPE html>
<html>
<head>
<title>Angular Js</title>
<link rel="stylesheet" type="text/css" href="bootstrap.min.css">
<script src="js/angular.js"></script>
</head>
<body ng-app="myApp">
<div class="header">
<div class="container">
<h1>book end</h1>
</div>
</div>
<div class="Main" ng-controller="MainController">
<div class="container" ng-model="title">
<h1>{{ title }}</h1>
</div>
</div>
<div class="footer">
<div class="container">
<h2>Available for iphone and android</h2>
<img src="http://lorempixel.com/400/200/">
<img src="http://lorempixel.com/400/200/">
</div>
</div>
<!--here you had these two lines inverted-->
<script src="js/App.js"></script> <!--first "declare" app-->
<script src="js/Controller/MainController.js"></script> <!--then, load modules, controller, etc-->
</body>
</html>
MainController.js
var app = angular.module('myApp'); //need to locate the module you want to register the controller
app.controller('MainController',['$scope',function($scope){
//it's '$scope', not '$scoope'
$scope.title = "top sellers in books";
}]);

Related

Angularjs ui-view not working

ui-view is not working and there is no error shown. What did I miss? Please help me out and make this work.
This is my index.html which is the main template.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script
src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script
src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script
src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<script
src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular-route.js"></script>
<script type="text/javascript" src="app.js"></script>
<script type="text/javascript" src="LoginPage.js"></script>
</head>
<body ng-app="Project">
<div class="mainbox">
<div class="loginmsg">
<div class="row text-center">
<p id="title">
<b>Movie Baba</b>
</p>
</div>
</div>
<div class="row">
<div ui-view></div>
</div>
</div>
</body>
</html>
Here LoginPage.js which I have included in the script tag is the controller for LoginPage.html
app.js is the config file which contains the states.
var Project = angular.module('Project', [ 'ui.router' ]);
Project.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/login');
$stateProvider.state('login',{
url : '/login',
templateUrl : 'LoginPage.html',
controller : 'LoginCtrl'
})
});
The following is the LoginPage.html which I'm trying to load/render using ui-view in index.html
<div class="row">
<div class="col-md-3">
<label>Username : </label>
</div>
<div class="col-md-9">
<input class="form-control" type="text" id="username" ng-model="user.username" name="username" maxlength="50"required>
</div>
</div>
ngRoute and ui.router are different libraries.
You should be importing the right script:
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/1.0.3/angular-ui-router.js"></script>
(Instead of /angular-route.js)
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/1.0.3/angular-ui-router.js"></script>
</head>
<body ng-app="Project">
<div class="mainbox">
<div class="loginmsg">
<div class="row text-center">
<p id="title">
<b>Movie Baba</b>
</p>
</div>
</div>
<div class="row">
<div ui-view></div>
</div>
</div>
<script type="text/ng-template" id="LoginPage.html">
<div class="row">
<div class="col-md-3">
<label>Username : </label>
</div>
<div class="col-md-9">
<input class="form-control" type="text" id="username" ng-model="user.username" name="username" maxlength="50" required>
</div>
</div>
</script>
<script>
var Project = angular.module('Project', ['ui.router']);
Project.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/login');
$stateProvider.state('login', {
url: '/login',
templateUrl: 'LoginPage.html'
})
});
</script>
</body>
</html>
Notice that you also load up ui-router in addition to loading Angular:
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.8/angular-ui-router.min.js"></script>
When creating a link with UI-Router, you will use ui-sref:for example:
<body ng-app="Project">
<div class="mainbox">
<div class="loginmsg">
<div class="row text-center">
<p id="title">
<b>Movie Baba</b>
</p>
</div>
</div>
<ul>
<li><a ui-sref="login">login</a></li>
</ul>
<div class="row">
<div ui-view></div>
</div>
</div>
</body>
The href will be generated from this and you want this to point to a certain state of your application.

How to use same ng-app for 2 different html page?

I have 2 html page and one app.js
my search-movie.html code as the following :
<!DOCTYPE html>
<html ng-app="adphorusWork">
<head lang="en">
<meta charset="UTF-8">
<title>Search Movie</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<script src="scripts/angular.min.js"></script>
<script src="scripts/angular-route.min.js"></script>
<script src="scripts/jquery-1.9.1.min.js"></script>
<script src="app/app.js"></script>
</head>
<body ng-controller="searchMovieController">
<div class="navbar navbar-default navbar-fixed-top" style="margin-top: 20px;">
<div class="container-fluid">
<ul>
<li>
OMDb Api
</li>
</ul>
</div>
</div>
<div class="container" style="margin-top: 50px;">
<div class="bs-docs-section" id="">
<div class="row">
<div class="col-lg-12">
<div class="page-header">
<h2>My Github</h2>
</div>
<div class="bs-component">
<form class="well form-search" id="search-movie" onsubmit="return false;">
<fieldset>
<legend>Search Movie</legend>
</fieldset>
<div>
<label class="control-label" for="movie-name">Movie Name : </label>
<input type="text" id="movie-name" class="input-small" style="margin-left: 10px;">
<button id="btn-search-movie" type="button" class="btn-sm btn-primary" style="margin-left: 10px;" ng-click="searchMovie()">
<span class="glyphicon glyphicon-search"> Search</span>
</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
and my result-movie.html code as the following :
<!DOCTYPE html>
<html>
<head ng-app="adphorusWork">
<meta charset="UTF-8">
<title>Search Movie</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<script src="scripts/angular.min.js"></script>
<script src="scripts/angular-route.min.js"></script>
<script src="app/app.js"></script>
<script src="scripts/jquery-1.9.1.min.js"></script>
</head>
<body ng-controller="resultMovieController">
<div class="navbar navbar-default navbar-fixed-top" style="margin-top: 20px;">
<div class="container-fluid">
<ul>
<li>
OMDb Api
</li>
</ul>
</div>
</div>
<div class="container" style="margin-top: 50px;">
<div class="bs-docs-section" id="">
<div class="row">
<div class="col-lg-12">
<div class="page-header">
<h2>My Github</h2>
</div>
<div class="bs-component">
<fieldset>
<legend>Result for Search Movie</legend>
</fieldset>
<div>
<button id="btn-result-movie" type="button" class="btn-sm btn-primary" style="margin-top: 40px;" ng-click="backtohome()">
<span class="glyphicon glyphicon-circle-arrow-left"> Home</span>
</button>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
and my app.js as the following :
(function (angular) {
'use strict';
var app = angular.module('adphorusWork', []);
app.controller('searchMovieController', function ($scope) {
$scope.searchMovie = function () {
alert("come")
}
});
app.controller('resultMovieController', function ($scope) {
$scope.backtohome = function () {
alert("home")
}
});
})(angular);
My search button is working (in search-movie.html) but my 'Home' button not working(in result-movie.html)
I'm using the same ng-app in two html page. I want to work on other button(so Home button)
Where am I doing wrong ? or How can I fix this error ?
you need to use Angular Ui router for this. And #Lex is correct you are not following the angular SPA framewrok.
This is a good read :https://github.com/angular-ui/ui-router
this link can provide a brief detail about angular ui router https://scotch.io/tutorials/angular-routing-using-ui-router
You don't have:
<script src="app/app.js"></script>
in your result-movie.html page. The bigger question, though, is why are you structuring it like this? Angular is designed as a single page application (SPA) framework. The way you are buidling it I think you are going to end up with a lot of issues long term.
I have noticed that you not include in result-movie.html page
<script src="app/app.js"></script>
as for best approach is you can use ngRoutefor data passing between controllers

isteven-multi-select output model not working with templates

I am using isteven-multi-select in my application for multiple selection. Everything works fine until I add isteven-multi-select div in another template. In that case, I dont get any values in output-model.
Plunker
Here , I am addding it in another template
<body ng-controller="MainCtrl">
<div ng-include="'test.html'"></div>
<button ng-click="a()">Print output</button>
<p>selected scope: {{ selectedScope }}</p>
</body>
test.html --
<section>
<div>
<div isteven-multi-select
input-model="scopes"
output-model="selectedScope"
button-label="name"
item-label="name"
tick-property="ticked"
>
</div>
</div>
</section>
ng-include creates new scope that inherits all parents scope properties. So you should pass parents selectedScope to output-model attribute:
<section>
<div>
<div isteven-multi-select
input-model="scopes"
output-model="$parent.selectedScope"
button-label="name"
item-label="name"
tick-property="ticked"
>
</div>
</div>
</section>
You can read this article for better understanding of scopes.
it works once you include the element in your main controller view
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js#1.2.x" src="https://code.angularjs.org/1.2.21/angular.js" data-semver="1.2.21"></script>
<link rel="stylesheet" href="angular-multi-select.css" />
<script src="angular-multi-select.js"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
<section>
<div>
<div isteven-multi-select
input-model="scopes"
output-model="selectedScope"
button-label="name"
item-label="name"
tick-property="ticked"
>
</div>
</div>
</section>
<button ng-click="a()">Print output</button>
<p>selected scope: {{ selectedScope }}</p>
<p>selected scope: {{ scopes }}</p>
</body>
</html>

AngularJS ng-model not working?

I have this index.html which has a navbar in the which is seen on all pages of my single page application. The navbars container div is using the ng-controller="LoginCtrl" value, so I will also include that controller from my angular application (app.js)
For some reason, the variables username and password which are bound via ng-model are showing as undefined when doLogin() is called via ng-click directive? That is after I type values into the text boxes that are bound to my controllers variables.
index.html
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet">
<link href="stylesheet.css" rel="stylesheet">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular-route.min.js"></script>
<base href="/">
<script src="https://cdnjs.cloudflare.com/ajax/libs/ngStorage/0.3.9/ngStorage.js"></script>
<script src="https://cdn.socket.io/socket.io-1.3.5.js"></script>
</head>
<body>
<div ng-controller="LoginCtrl">
<nav class="navbar navbar-default">
<div class="container">
<div class="navbar-header">
<a class="navbar-brand" href="#">TriviaAttack!</a>
</div>
<div id="navbar" class="navbar-collapse collapse">
<form ng-if="!loggedIn" id="loginForm" class="navbar-form navbar-right">
<div class="form-group">
<input type="text" placeholder="Email" class="form-control" ng-model="username">
</div>
<div class="form-group">
<input type="text" placeholder="Password" class="form-control" ng-model="password">
</div>
<div class="form-group">
<button type="submit" class="btn btn-success" ng-click="doLogin()">Sign In</button>
</div>
</form>
</div>
</div>
</nav>
<div ng-view></div>
</div>
<script src="./app/app.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js">
</body>
</html>
app.js
...
myApp.controller('LoginCtrl', function($rootScope, $location, AuthService, AuthToken) {
$rootScope.doLogin = function() {
console.log($rootScope.username);
console.log($rootScope.password);
}
});
...
An inputModel primitive property will be created on that ng-controller's scope when you type into the text field. input model is generated in the current scope, not the rootScope.
var app = angular.module('myApp', []);
app.controller('LoginCtrl', function($scope, $http) {
$scope.doLogin = function() {
console.log($scope.username);
console.log($scope.password);
}
});
Check it out on Plunker
Use model rather than using primitive types.
You should use $rootScope.user.name (ng-model will be user.name) rather than using $rootScope.username and $rootScope.user.password(ng-model will be user.password) instead of $rootScope.password
This problem actually happens for javascript's prototypical model. And if you want to know it's applicability in angularjs, you can go through this article. This will definitely help :)
Edit: As you are running into problem making that code work, I've made a working copy of your code. Please have a look at it:
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet">
<link href="stylesheet.css" rel="stylesheet">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular-route.min.js"></script>
<base href="/">
<script src="https://cdnjs.cloudflare.com/ajax/libs/ngStorage/0.3.9/ngStorage.js"></script>
<script src="https://cdn.socket.io/socket.io-1.3.5.js"></script>
</head>
<body>
<div ng-controller="LoginCtrl">
<nav class="navbar navbar-default">
<div class="container">
<div class="navbar-header">
<a class="navbar-brand" href="#">TriviaAttack!</a>
</div>
<div id="navbar" class="navbar-collapse collapse">
<form ng-if="!loggedIn" id="loginForm" class="navbar-form navbar-right">
<div class="form-group">
<input type="text" placeholder="Email" class="form-control" ng-model="user.name">
</div>
<div class="form-group">
<input type="text" placeholder="Password" class="form-control" ng-model="user.password">
</div>
<div class="form-group">
<button type="submit" class="btn btn-success" ng-click="doLogin()">Sign In</button>
</div>
</form>
</div>
</div>
</nav>
<div ng-view></div>
</div>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
</body>
</html>
<script>
var myApp = angular.module("myApp", []);
myApp.controller('LoginCtrl', function ($scope, $location) {
$scope.user = { name: "", password: "" };
$scope.doLogin = function () {
console.log($scope.user.name);
console.log($scope.user.password);
}
});
</script>
use $scope instead of $rootScope for getting the ng-model in controller.
I found the answer to my own question after some frustration. Adding username and password arguments to my doLogin() function, then using the directive ng-click="doLogin(user.name, user.pass)" works as I wanted. No clue why it wasn't working the way I was trying, but oh well.

How to split files for Angular multiple modules page?

I've followed this answer for making a multiple modules in AngularJS, but it doesn't work when I split the Angular codes into multiple js files.
Bootstrap.js
angular.bootstrap(document.getElementById("App2"),['namesList']);
HTML
<html>
<head>
<script src="components/angular/angular.js"></script>
<script src="scripts/module1.js"></script>
<script src="scripts/module2.js"></script>
<script src="scripts/bootstrap.js"></script>
</head>
<body>
<div id="App1" ng-app="shoppingCart" ng-controller="ShoppingCartController">
<h1>Your order</h1>
<div ng-repeat="item in items">
<span>{{item.product_name}}</span>
<span>{{item.price | currency}}</span>
<button ng-click="remove($index);">Remove</button>
</div>
</div>
<div id="App2" ng-app="namesList" ng-controller="NamesController">
<h1>List of Names</h1>
<div ng-repeat="_name in names">
<p>{{_name.username}}</p>
</div>
</div>
</body>
</html>
Result: the second module doesn't work.
Inline script
<html>
<head>
<script src="components/angular/angular.js"></script>
<script src="scripts/module1.js"></script>
<script src="scripts/module2.js"></script>
</head>
<body>
<div id="App1" ng-app="shoppingCart" ng-controller="ShoppingCartController">
<h1>Your order</h1>
<div ng-repeat="item in items">
<span>{{item.product_name}}</span>
<span>{{item.price | currency}}</span>
<button ng-click="remove($index);">Remove</button>
</div>
</div>
<div id="App2" ng-app="namesList" ng-controller="NamesController">
<h1>List of Names</h1>
<div ng-repeat="_name in names">
<p>{{_name.username}}</p>
</div>
</div>
<script>
angular.bootstrap(document.getElementById("App2"),['namesList']);
</script>
</body>
</html>
Result: it works.
Any ideas what I have missed?
in the first case you are executing the bootstrap.js before the dom gets loaded. This should work:
<html>
<head>
<script src="components/angular/angular.js"></script>
<script src="scripts/module1.js"></script>
<script src="scripts/module2.js"></script>
</head>
<body>
<div id="App1" ng-app="shoppingCart" ng-controller="ShoppingCartController">
<h1>Your order</h1>
<div ng-repeat="item in items">
<span>{{item.product_name}}</span>
<span>{{item.price | currency}}</span>
<button ng-click="remove($index);">Remove</button>
</div>
</div>
<div id="App2" ng-app="namesList" ng-controller="NamesController">
<h1>List of Names</h1>
<div ng-repeat="_name in names">
<p>{{_name.username}}</p>
</div>
</div>
<script src="scripts/bootstrap.js"></script>
</body>
</html>
alternatively you can wrap your bootstrap function into document ready and leave the bootstrap.js script in the head section:
angular.element(document).ready(function() {
angular.bootstrap(document.getElementById("App2"),['namesList']);
});

Categories

Resources