Related
So I am working on my very first MEAN stack app and I am using using type script.
I have my post working just fine, but my edit post is not working. Since this is my first app I am not quite sure why. The error says that my parameters for my post are undefined. I hope one of you lovely people can help me out. I've avoided asking for help for a long time because I am sure its a stupid error.
controllers.ts
http://pastebin.com/bhXT5bLz
app.ts
state('jobPost', {
url: '/jobPost',
templateUrl: "/templates/jobPost.html",
controller: MyApp.Controllers.jobPostController,
controllerAs: 'jobPost'
})
.state('editjobPost', {
url: '/editjobPost',
templateUrl: "/templates/jobPost.html",
controller: MyApp.Controllers.jobPostController,
controllerAs: 'jobPost'
})
route.ts:
router.get('/jobPostData', function (req, res) {
console.log('getting jobPost data');
JobPost.find({}, function(err, jobposts) {
res.json(jobposts);
});
});
router.put('/jobPost', function (req, res, next) {
console.log('editing jobPost');
let jobPost = new JobPost({
jobTitle: req.body.jobTitle,
jobLocation: req.body.jobLocation,
jobDescription: req.body.jobDescription,
created_at: req.body.created_at
});
console.log(jobPost);
jobPost.save(function(err, jobPost) {
if (err) return next(err);
console.log('edited post');
res.send(jobPost);
});
});
jobPost.html:
<link rel="stylesheet" href="/css/jobPost.css" media="screen" title="no title" charset="utf-8">
<br><br><br><br><br><br><br>
<div class="container-fluid">
<div class="container">
<div class="row">
<div ng-show="jobPost.newForm" class="col-md-12" id="background">
<h1 class="headers">Post a Job</h1>
<form ng-submit="jobPost.newJobPost()" class="new_job_form" name="new_job_form">
<input ng-model="jobPost.jobPost.title" id="jobTitle" type="text" name="jobTitle" placeholder="job title"> <br><br>
<input ng-model="jobPost.jobPost.location" id="jobLocation" type="text" name="jobLocation" placeholder="job location"> <br><br>
<textarea ng-model="jobPost.jobPost.description" rows="8" cols="50"class="input-block-level" id="jobDescription" name="jobDescription" placeholder="Enter Description" ></textarea><br>
<input class="submit-btn" type="submit" name="submit" value="Submit">
</form>
<!-- <h2>{{jobPost.message}}</h2> -->
</div>
<div ng-show="jobPost.editForm" class="col-md-12" id="background">
<h1 class="headers">Edit a Job</h1>
<form ng-submit="jobPost.editJobPost()" class="edit_job_form" name="edit_job_form">
<input ng-model="jobPost.jobPost.title" type="text" name="jobTitle" value="{{editJobPost.editTitle}}"> <br><br>
<input ng-model="jobPost.jobPost.location" type="text" name="jobLocation" value="{{editJobPost.editLocation}}"> <br><br>
<textarea ng-model="jobPost.jobPost.description" rows="8" cols="50"class="input-block-level" name="jobDescription" value="{{editJobPost.editDescription}}" ></textarea><br>
<input class="submit-btn" type="submit" name="submit" value="Submit">
</form>
</div>
</div
</div>
</div>
</div>
<br><br>
<div class="container-fluid">
<div class="container">
<h1 class="headers">Your Jobs</h1>
<div class="row" ng-repeat="job in jobPost.jobPosts.slice(((jobPost.currentPage-1)*jobPost.itemsPerPage),((jobPost.currentPage)*jobPost.itemsPerPage)) | orderBy : 'created_at' ">
<h1></h1>
<div class="col-md-12 jobPosting panel-title">
<h2>{{job.jobTitle}}<a class="pull-right" ui-sref="editjobPost"><span ng-click="jobPost.editJobPost()" class="glyphicon glyphicon-cog"></a></h2>
<h3>{{job.jobLocation}}</h3>
<h3>{{job.jobDescription}}</h3>
</div>
</div>
<!-- <pagination total-items="jobPost.totalItems" ng-model="jobPost.currentPage" ng-change="jobPost.pageChanged()" class="pagination-sm" items-per-page="jobPost.itemsPerPage"></pagination> -->
<ul uib-pagination total-items="jobPost.totalItems" items-per-page="jobPost.itemsPerPage" ng-model="jobPost.currentPage" ng-change="jobPost.pageChanged()"></ul>
<!-- <ul uib-pagination total-items="totalItems" ng-model="JobPost" ng-change="pageChanged()"></ul> -->
<!-- <h4>Default</h4>
<h5>totalItems: {{jobPost.totalItems}}</h5>
<ul uib-pagination total-items="jobPost.totalItems" ng-model="jobPost.currentPage" ng-change="jobPost.pageChanged()"></ul> -->
<!-- <ul uib-pagination boundary-links="true" total-items="jobPost.totalItems" ng-model="jobPost.currentPage" class="pagination-sm" previous-text="‹" next-text="›" first-text="«" last-text="»"></ul>
<ul uib-pagination direction-links="false" boundary-links="true" total-items="jobPost.totalItems" ng-model="jobPost.currentPage"></ul>
<ul uib-pagination direction-links="false" total-items="jobPost.totalItems" ng-model="jobPost.currentPage" num-pages="smallnumPages"></ul>
<pre>The selected page no: {{jobPost.currentPage}}</pre>
<button type="button" class="btn btn-info" ng-click="jobPost.setPage(3)">Set current page to: 3</button> -->
<hr />
</div>
</div>
<script src="/js/jobForm.js" charset="utf-8"></script>
jobForm.ts:
$(document).ready(function() {
$('.new_job_form').on('submit', function(e){
e.preventDefault();
var jobTitle = $('#jobTitle').val();
var jobLocation = $('#jobLocation').val();
var jobDescription = $('#jobDescription').val();
$('#jobTitle').val('');
$('#jobLocation').val('');
$('#jobDescription').val('');
var data = {
jobTitle: jobTitle,
jobLocation: jobLocation,
jobDescription: jobDescription,
};
console.log(data);
$.ajax({
url: '/jobPost',
dataType: "json",
method: "POST",
data: data,
success: function(data, textStatus, jqXHR){
console.log("Successfully saved to database",data);
// var resultString = "<h4>"+data.jobTitle+"</h4><h4>"+data.jobLocation+"</h4><h4>"+data.jobDescription+"</h4>";
// $('.postResult').html(resultString);
},
error: function(XMLHttpRequest, textStatus, errorThrown){
alert("Status: " + textStatus); alert("Error: " + errorThrown);
}
});
});
angular.module('MyApp').controller('jobPostController', function ($scope, $log) {
$scope.totalItems = 64;
$scope.currentPage = 1;
$scope.setPage = function (pageNo) {
$scope.currentPage = pageNo;
};
$scope.pageChanged = function() {
$log.log('Page changed to: ' + $scope.currentPage);
};
$scope.maxSize = 5;
$scope.bigTotalItems = 175;
$scope.bigCurrentPage = 1;
});
});
****EDIT to reflect answering stack overflow checklist
I have tried messing with the ui-sref and ng-click for the editJobPost section in the JobPost.html thinking maybe it was a routing error.
I then changed the editJobPost method in controller.js from the JobPost variable to JobPosts variable. Now that it runs and compiles (it didn't before) it throws this in the console:
HITTING EDIT
controllers.js:241 undefined
controllers.js:242 undefined
controllers.js:245 undefined
controllers.js:249 Title: undefined
controllers.js:250 Location: undefined
controllers.js:251 Description: undefined
angular.js:11881 PUT http://127.0.0.1:3000/jobPost/%7B%7Bjob._id%7D%7D 404 (Not Found)
I know that it means my declared variables are undefined, I just don't know where to start. what is wrong and why.
what i m doing:
simple html file shows first page , in this page i have one title and button, initially i set $scope.index = 0. so, we set first position of array. when we click on next button it finds firstCtrl and first.html page. in this controller i update $scope.index by 1. so, my question is when i update $scope.index of myCtrl then $scope.index is changed on another controller i wants to change myCtrl. is it possible ? if it is then help me.
index.html:
<body ng-controller="myCtrl">
<div id="navbar">
<div class="setToggle">
<input id="slide-sidebar" type="checkbox" role="button" />
<label for="slide-sidebar"><span class="glyphicon glyphicon-menu-hamburger"></span></label>
</div>
<div class="setQuestion">
<h2>{{surveys[index].questionTitle}}</h2>
</div>
</div>
<div class="content-wrapper" class="container-fluid">
<div class="sidebar-left">
<div class="first">
<ul ng-repeat="cat in surveys[index].category" class="list-unstyled" ng-hide="checkSubCategoryValueIsNull.length">
<li class="category">
<a ng-click="expand=!expand">
<span class="glyphicon" ng-class="{'glyphicon-plus': !expand, 'glyphicon-minus': expand}">
{{cat.categoryName}}
</span>
</a>
</li>
<ul ng-repeat="subcategory in cat.categoryItemDto" class="list-unstyled">
<li ng-show="expand">
<label class="label-style-change">
<input type="checkbox" ng-click="toggleSelectionCheckbox(surveys[index], subcategory)" ng-model="subcategory.selectValue" ng-disabled="disableCheckbox">
<span class="subcategory-item" ng-disabled="disableCheckbox">{{subcategory.subCategoryName}}</span>
</label>
</li>
</ul>
</ul>
</div>
<div class="second">
<input type="button" name="Submit" value="Submit" ng-click="submitSelection()" ng-hide="hideSubmitButton" ng-disabled="!selections[index].length">
<input type="button" name="Edit" value="Edit" ng-click="EditSelection()" ng-show="hideEditButton">
</div>
</div>
<div class="portfolio">
<div id="main">
<div ng-view></div>
</div>
</div>
</div>
</body>
controller.js
(function() {
var app = angular.module("app.controllers", ["app.service"]);
app.controller("myCtrl", ["$scope", "$http", "$location", "$timeout", "surveyService", "Data",
function ($scope, $http, $location, $timeout, surveyService, Data) {
surveyService.getData(function(dataResponse) {
$scope.surveys = dataResponse;
$scope.selections = [];
/* create 2d array mannually */
var numInternalArrays = $scope.surveys.length;
for (var i = 0; i < numInternalArrays; i++) {
$scope.selections[i] = [];
};
$scope.index = 0;
var toggleCheckboxFlag = 0;
/* PRIVATE FUNCTION
for find value from selections array and replace it
*/
function findAndRemove(array, property, value) {
array.forEach(function(result, index) {
if(result[property] === value) {
array.splice(index, 1);
toggleCheckboxFlag = 1;
}
});
}
$scope.toggleSelectionCheckbox = function (QuestionId, value) {
toggleCheckboxFlag = 0;
if (!value) return;
findAndRemove($scope.selections[$scope.index], 'categoryId', value.subCategoryId);
if (toggleCheckboxFlag != 1) {
$scope.selections[$scope.index].push({
questionId: QuestionId.questionId,
categoryId: value.subCategoryId,
categoryName: value.subCategoryName,
storeId: 1,
comment: ""
});
}
};
$scope.submitSelection = function() {
$scope.value = $scope.selections[$scope.index];
$scope.hideSubmitButton = true;
$scope.disableCheckbox = true;
$scope.hideEditButton = true;
$location.path("/question/1");
}
});
$scope.EditSelection = function() {
$scope.hideEditButton = false;
$scope.hideSubmitButton = false;
$scope.disableCheckbox = false;
$scope.value = false;
}
$scope.$watch('index', function (newValue, oldValue) {
if (newValue !== oldValue) Data.setIndex(newValue);
});
console.log("controller", Data.getIndex())
}]);
})();
app.js
var app = angular.module('app', ['ngRoute','app.service', 'app.controllers']);
app.config(['$routeProvider', function($routeProvider) {
$routeProvider
.when('/question/1', {
templateUrl: 'views/first.html',
controller: 'sidebarCtrl'
})
.when('/question/2', {
templateUrl: 'views/second.html',
controller: 'mainCtrl'
})
.otherwise({
redirectTo: '/'
});
}]);
first.html
<div id="content-wrapper" ng-show="value">
<div class="col-lg-offset-1 col-lg-8 col-md-12 col-sm-12 col-xs-12">
<h2 class="subCategoryLabel"><span class="label">{{value[inc].categoryName}}</span></h2>
</div>
<div class="row">
<div class="col-lg-4 col-md-4 col-sm-4 col-xs-4">
<button class="btnNext" ng-hide="inc == 0" ng-click="prev()">
<i class="glyphicon glyphicon-menu-left"></i>
</button>
</div>
<div class="col-lg-4 col-md-4 col-sm-4 col-xs-4">
<form name="myForm">
<div ng-repeat="item in surveys[index].optionCategoryItemDto" class="formStyle">
<label class="text-center">
<input type="radio" name="radio" id="{{item.itemId}}" ng-value="item.itemId" ng-model="selections[index][inc].answer" required>
{{item.itemName}}
</label>
</div>
<br/>
<br/>
</form>
</div>
<div class="col-lg-3 col-lg-offset-1 col-md-offset-1 col-md-3 col-sm-4 col-xs-4">
<button class="btnNext" ng-hide="selections[index].length == inc + 1" ng-disabled="myForm.radio.$error.required" ng-click="next()">
<i class="glyphicon glyphicon-menu-right"></i>
</button>
<button class="btnNext" ng-show="selections[index].length == inc + 1" ng-disabled="myForm.radio.$error.required" ng-click="nextQuestion()">
<i class="glyphicon glyphicon-forward"></i>
</button>
</div>
</div>
<div class="col-lg-offset-3 col-lg-4 col-md-offset-3 col-md-6 col-sm-offset-3 col-sm-6 col-xs-4">
<textarea type="text" id="text" class="form-control txtArea" ng-model="selections[index][inc].comment" placeholder="Write comment..."></textarea>
</div>
</div>
sidebarCtrl.js
in this controller i update $scope.index when we call nextQuestion(). here $scope.index increment by one and $watch function also get latest value of index. but myCtrl is not update. i wants to update myCtrl.
(function() {
var app = angular.module("app.controllers");
app.controller("sidebarCtrl", ['$scope', "$location", "Data", function($scope, $location, Data) {
$scope.inc = 0;
$scope.next = function() {
$scope.inc += 1;
}
$scope.prev = function() {
$scope.inc -= 1;
}
$scope.nextQuestion = function() {
$scope.index += 1;
$location.path("/question/2");
}
$scope.$watch('index', function (newValue, oldValue) {
console.log("SASAS", newValue)
if (newValue !== oldValue) Data.setIndex(newValue);
});
}]);
})();
service.js
(function() {
var app = angular.module("app.service", []);
app.service("surveyService", function($http) {
this.getData = function (callbackFunc) {
$http({
method: "GET",
data: {something: true},
contentType: 'application/json',
dataType: 'jsonp',
url: "http://localhost:8080/TheSanshaWorld/sfcms/fetch-survey-details"
}).success(function(data){
callbackFunc(data);
}).error(function(){
alert("error");
});
};
this.setData = function(value) {
if (confirm('Do you wanna to submit?')) {
$http.post("http://localhost:8080/TheSanshaWorld/sfcms/save-survey-result-data", value).success(function(data, status) {
window.open("../index.html","_self");
});
} else {
return false;
}
};
});
app.factory('Data', function () {
var data = {
Index: ''
};
return {
getIndex: function () {
return data.Index;
},
setIndex: function (index) {
data.Index = index;
console.log("service", data.Index)
}
};
});
})();
Because sidebarCtrl is nested within myCtrl, therefore you can reach myCtrl $scope.index from sidebarCtrl using it $scope.$parent.index,
Try it by test: add any parameter value to myCtrl $scope.name='Bob';
then log it in sidebarCtrl console.log($scope.$parent.name); you should see printed 'Bob'. Do the same with index.
I have two templates with respective controllers and service files. One template's(fleetListTemplate) controller(fleetListController) loads data from its service file(fleetService) and displays in its view(fleetListTemplate).
When this happens, and I click on one of the loaded data from fleetService, I should link fleetListController to fleetSummaryController to get data from its service file (fleetSummaryService) and display in fleetSummaryTemplate view.
Can someone please help me with the coding? Thank you.
The following are the respective modules, templates, controllers and service files.
fleetListModule
"use strict";
angular.module("fleetListModule", []);
fleetListTemplate
<div class="panel1 panel-primary">
<div class="panel-heading" align="center">TRUCKS</div>
<table class="table table-bordered table-condensed table-striped">
<tr>
<th>TruckID</th>
<th>Status</th>
<th>Dest.</th>
<th>Alerts</th>
</tr>
<tr ng-repeat="truck in trucks" ng-click="summaryData()">
<td>{{truck.truckID}}</td>
<td>{{truck.status}}</td>
<td>{{truck.destination}}</td>
<td>{{truck.alerts}}</td>
</tr>
</table>
</div>
fleetListController
"use strict";
angular.module("fleetListModule").controller("fleetListController",
['$scope', 'fleetsService',
function ($scope, fleetsService) {
$scope.trucks = fleetsService.getTrucks();
$scope.summaryData = function () {
$rootScope.$broadcast('obtainSummary');
}
}]);
fleetSummaryModule
"use strict";
angular.module("fleetSummaryModule", []);
fleetSummaryTemplate
<div class="panel2 panel-primary">
<div class="panel-heading">Summary</div>
<table class="table table-bordered table-condensed table-striped">
<tr ng-repeat="summary in truckSummary">
<td>Truck ID: {{summary.truckID}}</td>
<td>Trailer ID: {{summary.trailerID}}</td>
<td>Driver ID: {{summary.driverID}}</td>
<td>Truck Number: {{summary.truckNumber}}</td>
<td>Trailer Number: {{summary.trailerNumber}}</td>
<td>Insurance Due Date: {{summary.insuranceDueDate}}</td>
<td>Maintenance Due Date: {{summary.maintenanceDueDate}}</td>
</tr>
</table>
</div>
fleetSummaryController
"use strict";
angular.module("fleetSummaryModule").controller("fleetSummaryController",
['$scope', 'fleetSummaryService',
function ($scope, fleetSummaryService) {
$scope.$on('obtainSummary', function (event, args) {
$scope.truckSummary = fleetSummaryService.getSummary();
})
}]);
fleetSummaryService
"use strict";
angular.module("fleetSummaryModule").service("fleetSummaryService",
function () {
this.getSummary = function () {
return summary;
};
this.getSummary = function (truckID) {
for (var i = 0, len = truckSummary.length; i < len; i++) {
if (truckSummary[i].truckID === parseInt(truckID)) {
return truckSummary[i];
}
}
return {};
};
var truckSummary = [
{
truckID: 1,
trailerID: '123',
driverID: 'Alex123',
truckNumber: 'hyt 583',
trailerNumber: 'xyz213',
insuranceDueDate: '25-12-2015',
maintenanceDueDate: '31-12-2015'
},
{
truckID: 2,
trailerID: '456',
driverID: 'Alex123',
truckNumber: 'hyt 583',
trailerNumber: 'xyz213',
insuranceDueDate: '25-12-2015',
maintenanceDueDate: '31-12-2015'
},
{
truckID: 3,
trailerID: '789',
driverID: 'Alex123',
truckNumber: 'hyt 583',
trailerNumber: 'xyz213',
insuranceDueDate: '25-12-2015',
maintenanceDueDate: '31-12-2015'
}
];
});
This simple example show to you how to share data between 2 controllers "in one app"
using common service.
angular.module("app", []);
///controller1
angular.module("app").controller("controller1", function ($scope, service) {
$scope.lists = [
{ name: "maher" },
{ name: "Gaurav Ram" },
{ name: "Shaun Scovil" }
];
$scope.send = function () {
service.set("lists", $scope.lists); //set(key, value)
$scope.lists = []; //optional
}
});
///controller2
angular.module("app").controller("controller2", function ($scope, service) {
$scope.lists = [];
//get data from broadcast on the root
service.get("lists"); // get(key)
//set data
$scope.resive = function () {
if (angular.isUndefined($scope.broadcast)) {
$scope.alert = "No data to resive!";
} else {
$scope.alert = null;
$scope.lists = $scope.broadcast;
}
}
});
///service
angular.module("app").service("service", function ($rootScope) {
this.set = function (key, value) {
$rootScope.$broadcast(key, value);
}
this.get = function (key) {
$rootScope.$on(key, function (event, data) {
$rootScope.broadcast = data;
});
}
});
<!doctype html>
<html ng-app="app">
<head>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" />
</head>
<body>
<div ng-controller="controller1" class="col-md-6 col-sm-6 col-xs-6">
<div class="page-header">
<h1>controller 1</h1>
</div>
<button ng-click="send()" class="btn btn-primary">Send</button>
<div class="clearfix"></div>
<br/>
<div class="alert alert-info" ng-if="lists.length == 0">Data <b>sent</b> to controller 2, click Resive button to get data</div>
<ul class="list-group">
<li ng-repeat="list in lists" class="list-group-item" ng-bind="list.name"></li>
</ul>
</div>
<div ng-controller="controller2" class="col-md-6 col-sm-6 col-xs-6">
<div class="page-header">
<h1>controller 2</h1>
</div>
<button ng-click="resive()" class="btn btn-success">Resive</button>
<div class="clearfix"></div>
<br />
<div class="alert alert-info" ng-bind="alert" ng-if="alert"></div>
<ul class="list-group">
<li ng-repeat="list in lists" class="list-group-item" ng-bind="list.name"></li>
</ul>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.8/angular.min.js"></script>
</body>
</html>
I am new to AngularJS and I'm facing these issues :
I want to have a list of items (movies) and when I click on the image or on the title I want the path to be like #/movie/id. For that I tried using ngRoute and also tried path but I have faced errors in both, can you guide me which one is suitable for my case and how can I use it?
As you can see in the HTML code, I am trying to draw a search box but right now when the API runs and returns data the whole content of the ng-app is being replaced with the movie list, should I create a new scope for just the content I want to change, if so how and where?
Here is my code:
var movies = angular.module("movies", []);
movies.controller('movieController', function ($scope, $http) {
$http.jsonp('http://api.rottentomatoes.com/api/public/v1.0/lists/movies/box_office.json', {
params: {
limit : 16,
country : 'us',
apikey: 'rssd8z7pfw5t4nyd3cpszzzm',
callback: 'JSON_CALLBACK'
}
})
.success(function (data) {
$scope.movies = data.movies;
});
});
//added ngroute
var app = angular.module('movies', ['ngRoute']);
app.config(
function($routeProvider) {
$routeProvider.
when('/', {templateUrl:'/'}).
when('/movie/:id',
{
controller:UserView,
templateUrl: function(params){ return '/moviessssssss/' + params.id; }
}
).
otherwise({redirectTo:'/'});
}
);
app.controller('UserView', function($scope) {
$scope.movies = 'hereeeeeee!';
});
<html ng-app="movies">
<head>
<link rel="stylesheet" hrf="//netdna.bootstrapcdn.com/font-awesome/4.0.0/css/font-awesome.css" />
<script src= "http://ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.5/angular-route.min.js"></script>
</head>
<body>
<div class="ng-scope">
Search : <input type="text" placeholder="filter for..." >
</div>
<div ng-view>
{{ message }}
<table ng-controller="movieController" class="ng-cloak">
<tr ng-repeat="movie in movies">
<td><a ng-href="#movie" ><img ng-src="{{ movie.posters.thumbnail}}"/></a></td>
<td><a ng-href="#movie" > {{ movie.title }} </a></td>
</tr>
</table>
</div>
For getting the links:
ng-href="{{'/#/movie/'+movie.id}}"
Then for getting the filter to work,
Put ng-model to your search box. And in your ng-repeat add | filter: ng-modelname
var movies = angular.module("movies", []);
movies.controller('movieController', function ($scope, $http) {
$http.jsonp('http://api.rottentomatoes.com/api/public/v1.0/lists/movies/box_office.json', {
params: {
limit : 16,
country : 'us',
apikey: 'rssd8z7pfw5t4nyd3cpszzzm',
callback: 'JSON_CALLBACK'
}
})
.success(function (data) {
$scope.movies = data.movies;
console.log($scope.movies);
});
});
<html ng-app="movies">
<head>
<link rel="stylesheet" hrf="//netdna.bootstrapcdn.com/font-awesome/4.0.0/css/font-awesome.css" />
<script src= "http://ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.5/angular-route.min.js"></script>
</head>
<body>
<div class="ng-scope">
Search : <input type="text" placeholder="filter for..." ng-model="search">
</div>
<div ng-view>
{{ message }}
<table ng-controller="movieController" class="ng-cloak">
<tr ng-repeat="movie in movies | filter:search">
<td><a ng-href="{{'/#/movie/'+movie.id}}" ><img ng-src="{{ movie.posters.thumbnail}}"/></a></td>
<td><a ng-href="{{'/#/movie/'+movie.id}}" > {{ movie.title }} </a></td>
</tr>
</table>
</div>
TL;DR
Click Here to see a live plunker example.
in my example, i used bootstrap. remove if irrelevant
there is a TODO in my plunker - the server side movie filtering (when you type a something in the search field). you need to read more about it in developer.rottentomatoes.com
This is the routing configuration i would define:
movies.config(function($routeProvider, $locationProvider) {
$routeProvider
.when('/movies', {
templateUrl: 'movies.html',
controller: 'MoviesController',
resolve: {
movies: function($http) {
return $http.jsonp('http://api.rottentomatoes.com/api/public/v1.0/lists/movies/box_office.json', {
params: {
limit: 16,
country: 'us',
apikey: 'rssd8z7pfw5t4nyd3cpszzzm',
callback: 'JSON_CALLBACK'
}
});
}
}
})
.when('/movies/:id', {
templateUrl: 'movie.html',
controller: 'MovieController',
resolve: {
movie: function($http, $route) {
var id = $route.current.params.id;
return $http.jsonp('http://api.rottentomatoes.com/api/public/v1.0/movies/' + id + '.json', {
params: {
limit: 1,
country: 'us',
apikey: 'rssd8z7pfw5t4nyd3cpszzzm',
callback: 'JSON_CALLBACK',
q: id
}
});
}
}
})
.otherwise({
redirectTo: '/movies'
});
});
/movies - a list of all movies
/movies/<movie id> - a specific details about the movie
NOTE - i used resolve to pre-fetch the json data (this is optional)
index.html
this is the main html code of your
<!DOCTYPE html>
<html ng-app="movies">
<head>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.25/angular.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.25/angular-route.js"></script>
<link href="//netdna.bootstrapcdn.com/twitter-bootstrap/3.2.0/css/bootstrap.min.css" rel="stylesheet">
<script src="app.js"></script>
</head>
<body>
<div class="container">
<div ng-view></div>
</div>
</body>
</html>
movies.html
the view of the movie list.
we get the specific movie redirect by <a ng-href="#/movies/{{movie.id}}">
<input class="form-control" type="text" placeholder="Search ..." ng-model="search" >
<hr>
<table>
<tr ng-repeat="movie in movies | filter:search">
<td><a ng-href="#/movies/{{movie.id}}" ><img ng-src="{{ movie.posters.thumbnail}}"/></a></td>
<td><a ng-href="#/movies/{{movie.id}}"> {{ movie.title }} </a></td>
</tr>
</table>
movie.html
the view of the specific movie
<img class="img-responsive" ng-src="{{ movie.posters.detailed}}"/>
<h3>{{movie.title}} <small>{{movie.year}}</small></h3>
<p>{{movie.synopsis}}</p>
<hr>
<a class="btn btn-default" href="#/movies">Back</a>
<hr>
<pre>{{movie | json}}</pre>
MoviesController
the controller attached to the movies.html view
the $scope.$watch('search', is required to query the server for each input change you make. it's currently not working properly; rottentomatoes.com ignoring the q param. you need to read more about it in developer.rottentomatoes.com
movies.controller('MoviesController', function($scope, $http, movies) {
$scope.search = '';
$scope.$watch('search', function(newValue) {
// TODO: you need to request again the movie list from the server.
// Read more about the API here:
// http://developer.rottentomatoes.com/docs/read/json/v10/Movies_Search
$http.jsonp('http://api.rottentomatoes.com/api/public/v1.0/lists/movies/box_office.json', {
params: {
limit: 16,
country: 'us',
apikey: 'rssd8z7pfw5t4nyd3cpszzzm',
callback: 'JSON_CALLBACK',
q: newValue
},
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
})
.success(function(data) {
console.log(data);
$scope.movies = data.movies;
});
});
$scope.movies = movies.data.movies;
});
MovieController
the controller attached to the movie.html view
movies.controller('MovieController', function($scope, movie) {
$scope.movie = movie.data;
});
Live example - http://plnkr.co/edit/cJXTZWqBUXNTPinf7AoV?p=preview
For your first question do this:
<td><a ng-href="#/movie/{{movie.id}}"> {{movie.title}} </a></td>
I have just started learning Angular JS and created some basic samples however I am stuck with the following problem.
I have created 2 modules and 2 controllers.
shoppingCart -> ShoppingCartController
namesList -> NamesController
There are associated views for each controller. The first View renders fine but second is not rendering. There are no errors.
http://jsfiddle.net/ep2sQ/
Please help me solve this issue.
Also is there any possibility to add console in View to check what values are passed from Controller.
e.g. in the following div can we add console.log and output the controller values
<div ng-app="shoppingCart" ng-controller="ShoppingCartController">
</div>
So basically as mentioned by Cherniv we need to bootstrap the modules to have multiple ng-app within the same page. Many thanks for all the inputs.
var shoppingCartModule = angular.module("shoppingCart", [])
shoppingCartModule.controller("ShoppingCartController",
function($scope) {
$scope.items = [{
product_name: "Product 1",
price: 50
}, {
product_name: "Product 2",
price: 20
}, {
product_name: "Product 3",
price: 180
}];
$scope.remove = function(index) {
$scope.items.splice(index, 1);
}
}
);
var namesModule = angular.module("namesList", [])
namesModule.controller("NamesController",
function($scope) {
$scope.names = [{
username: "Nitin"
}, {
username: "Mukesh"
}];
}
);
angular.bootstrap(document.getElementById("App2"), ['namesList']);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.3/angular.min.js"></script>
<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>
To run multiple applications in an HTML document you must manually bootstrap them using angular.bootstrap()
HTML
<!-- Automatic Initialization -->
<div ng-app="myFirstModule">
...
</div>
<!-- Need To Manually Bootstrap All Other Modules -->
<div id="module2">
...
</div>
JS
angular.
bootstrap(document.getElementById("module2"), ['mySecondModule']);
The reason for this is that only one AngularJS application can be automatically bootstrapped per HTML document. The first ng-app found in the document will be used to define the root element to auto-bootstrap as an application.
In other words, while it is technically possible to have several applications per page, only one ng-app directive will be automatically instantiated and initialized by the Angular framework.
You can use angular.bootstrap() directly... the problem is you lose the benefits of directives.
First you need to get a reference to the HTML element in order to bootstrap it, which means your code is now coupled to your HTML.
Secondly the association between the two is not as apparent. With ngApp you can clearly see what HTML is associated with what module and you know where to look for that information. But angular.bootstrap() could be invoked from anywhere in your code.
If you are going to do it at all the best way would be by using a directive. Which is what I did. It's called ngModule. Here is what your code would look like using it:
<!DOCTYPE html>
<html>
<head>
<script src="angular.js"></script>
<script src="angular.ng-modules.js"></script>
<script>
var moduleA = angular.module("MyModuleA", []);
moduleA.controller("MyControllerA", function($scope) {
$scope.name = "Bob A";
});
var moduleB = angular.module("MyModuleB", []);
moduleB.controller("MyControllerB", function($scope) {
$scope.name = "Steve B";
});
</script>
</head>
<body>
<div ng-modules="MyModuleA, MyModuleB">
<h1>Module A, B</h1>
<div ng-controller="MyControllerA">
{{name}}
</div>
<div ng-controller="MyControllerB">
{{name}}
</div>
</div>
<div ng-module="MyModuleB">
<h1>Just Module B</h1>
<div ng-controller="MyControllerB">
{{name}}
</div>
</div>
</body>
</html>
You can get the source code for it at:
http://www.simplygoodcode.com/2014/04/angularjs-getting-around-ngapp-limitations-with-ngmodule/
It's implemented in the same way as ngApp. It simply calls angular.bootstrap() behind the scenes.
In my case I had to wrap the bootstrapping of my second app in angular.element(document).ready for it to work:
angular.element(document).ready(function() {
angular.bootstrap(document.getElementById("app2"), ["app2"]);
});
Here's an example of two applications in one html page and two conrollers in one application :
<div ng-app = "myapp">
<div ng-controller = "C1" id="D1">
<h2>controller 1 in app 1 <span id="titre">{{s1.title}}</span> !</h2>
</div>
<div ng-controller = "C2" id="D2">
<h2>controller 2 in app 1 <span id="titre">{{s2.valeur}}</span> !</h2>
</div>
</div>
<script>
var A1 = angular.module("myapp", [])
A1.controller("C1", function($scope) {
$scope.s1 = {};
$scope.s1.title = "Titre 1";
});
A1.controller("C2", function($scope) {
$scope.s2 = {};
$scope.s2.valeur = "Valeur 2";
});
</script>
<div ng-app="toapp" ng-controller="C1" id="App2">
<br>controller 1 in app 2
<br>First Name: <input type = "text" ng-model = "student.firstName">
<br>Last Name : <input type="text" ng-model="student.lastName">
<br>Hello : {{student.fullName()}}
<br>
</div>
<script>
var A2 = angular.module("toapp", []);
A2.controller("C1", function($scope) {
$scope.student={
firstName:"M",
lastName:"E",
fullName:function(){
var so=$scope.student;
return so.firstName+" "+so.lastName;
}
};
});
angular.bootstrap(document.getElementById("App2"), ['toapp']);
</script>
<style>
#titre{color:red;}
#D1{ background-color:gray; width:50%; height:20%;}
#D2{ background-color:yellow; width:50%; height:20%;}
input{ font-weight: bold; }
</style>
You can merge multiple modules in one rootModule , and assign that module as
ng-app to a superior element ex: body tag.
code ex:
<!DOCTYPE html>
<html>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<script src="namesController.js"></script>
<script src="myController.js"></script>
<script>var rootApp = angular.module('rootApp', ['myApp1','myApp2'])</script>
<body ng-app="rootApp">
<div ng-app="myApp1" ng-controller="myCtrl" >
First Name: <input type="text" ng-model="firstName"><br>
Last Name: <input type="text" ng-model="lastName"><br>
<br>
Full Name: {{firstName + " " + lastName}}
</div>
<div ng-app="myApp2" ng-controller="namesCtrl">
<ul>
<li ng-bind="first">{{first}}
</li>
</ul>
</div>
</body>
</html>
var shoppingCartModule = angular.module("shoppingCart", [])
shoppingCartModule.controller("ShoppingCartController",
function($scope) {
$scope.items = [{
product_name: "Product 1",
price: 50
}, {
product_name: "Product 2",
price: 20
}, {
product_name: "Product 3",
price: 180
}];
$scope.remove = function(index) {
$scope.items.splice(index, 1);
}
}
);
var namesModule = angular.module("namesList", [])
namesModule.controller("NamesController",
function($scope) {
$scope.names = [{
username: "Nitin"
}, {
username: "Mukesh"
}];
}
);
var namesModule = angular.module("namesList2", [])
namesModule.controller("NamesController",
function($scope) {
$scope.names = [{
username: "Nitin"
}, {
username: "Mukesh"
}];
}
);
angular.element(document).ready(function() {
angular.bootstrap(document.getElementById("App2"), ['namesList']);
angular.bootstrap(document.getElementById("App3"), ['namesList2']);
});
<!DOCTYPE html>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.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>
<div id="App3" ng-app="namesList2" ng-controller="NamesController">
<h1>List of Names</h1>
<div ng-repeat="_name in names">
<p>{{_name.username}}</p>
</div>
</div>
</body>
</html>
// root-app
const rootApp = angular.module('root-app', ['app1', 'app2E']);
// app1
const app11aa = angular.module('app1', []);
app11aa.controller('main', function($scope) {
$scope.msg = 'App 1';
});
// app2
const app2 = angular.module('app2E', []);
app2.controller('mainB', function($scope) {
$scope.msg = 'App 2';
});
// bootstrap
angular.bootstrap(document.querySelector('#app1a'), ['app1']);
angular.bootstrap(document.querySelector('#app2b'), ['app2E']);
<!-- angularjs#1.7.0 -->
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.7.0/angular.min.js"></script>
<!-- root-app -->
<div ng-app="root-app">
<!-- app1 -->
<div id="app1a">
<div ng-controller="main">
{{msg}}
</div>
</div>
<!-- app2 -->
<div id="app2b">
<div ng-controller="mainB">
{{msg}}
</div>
</div>
</div>
Only one app is automatically initialized. Others have to manually initialized as follows:
Syntax:
angular.bootstrap(element, [modules]);
Example:
<!DOCTYPE html>
<html>
<head>
<script src="https://code.angularjs.org/1.5.8/angular.js" data-semver="1.5.8" data-require="angular.js#1.5.8"></script>
<script data-require="ui-router#0.2.18" data-semver="0.2.18" src="//cdn.rawgit.com/angular-ui/ui-router/0.2.18/release/angular-ui-router.js"></script>
<link rel="stylesheet" href="style.css" />
<script>
var parentApp = angular.module('parentApp', [])
.controller('MainParentCtrl', function($scope) {
$scope.name = 'universe';
});
var childApp = angular.module('childApp', ['parentApp'])
.controller('MainChildCtrl', function($scope) {
$scope.name = 'world';
});
angular.element(document).ready(function() {
angular.bootstrap(document.getElementById('childApp'), ['childApp']);
});
</script>
</head>
<body>
<div id="childApp">
<div ng-controller="MainParentCtrl">
Hello {{name}} !
<div>
<div ng-controller="MainChildCtrl">
Hello {{name}} !
</div>
</div>
</div>
</div>
</body>
</html>
AngularJS API
You can define a Root ng-App and in this ng-App you can define multiple nd-Controler. Like this
<!DOCTYPE html>
<html>
<script src = "https://ajax.googleapis.com/ajax/libs/angularjs/1.3.3/angular.min.js"></script>
<style>
table, th , td {
border: 1px solid grey;
border-collapse: collapse;
padding: 5px;
}
table tr:nth-child(odd) {
background-color: #f2f2f2;
}
table tr:nth-child(even) {
background-color: #ffffff;
}
</style>
<script>
var mainApp = angular.module("mainApp", []);
mainApp.controller('studentController1', function ($scope) {
$scope.student = {
firstName: "MUKESH",
lastName: "Paswan",
fullName: function () {
var studentObject;
studentObject = $scope.student;
return studentObject.firstName + " " + studentObject.lastName;
}
};
});
mainApp.controller('studentController2', function ($scope) {
$scope.student = {
firstName: "Mahesh",
lastName: "Parashar",
fees: 500,
subjects: [
{ name: 'Physics', marks: 70 },
{ name: 'Chemistry', marks: 80 },
{ name: 'Math', marks: 65 },
{ name: 'English', marks: 75 },
{ name: 'Hindi', marks: 67 }
],
fullName: function () {
var studentObject;
studentObject = $scope.student;
return studentObject.firstName + " " + studentObject.lastName;
}
};
});
</script>
<body>
<div ng-app = "mainApp">
<div id="dv1" ng-controller = "studentController1">
Enter first name: <input type = "text" ng-model = "student.firstName"><br/><br/> Enter last name: <input type = "text" ng-model = "student.lastName"><br/>
<br/>
You are entering: {{student.fullName()}}
</div>
<div id="dv2" ng-controller = "studentController2">
<table border = "0">
<tr>
<td>Enter first name:</td>
<td><input type = "text" ng-model = "student.firstName"></td>
</tr>
<tr>
<td>Enter last name: </td>
<td>
<input type = "text" ng-model = "student.lastName">
</td>
</tr>
<tr>
<td>Name: </td>
<td>{{student.fullName()}}</td>
</tr>
<tr>
<td>Subject:</td>
<td>
<table>
<tr>
<th>Name</th>.
<th>Marks</th>
</tr>
<tr ng-repeat = "subject in student.subjects">
<td>{{ subject.name }}</td>
<td>{{ subject.marks }}</td>
</tr>
</table>
</td>
</tr>
</table>
</div>
</div>
</body>
</html>
I have modified your jsfiddle, can make top most module as rootModule for rest of the modules.
Below Modifications updated on your jsfiddle.
Second Module can injected in RootModule.
In Html second defined ng-app placed inside the Root ng-app.
Updated JsFiddle:
http://jsfiddle.net/ep2sQ/1011/
Use angular.bootstrap(element, [modules], [config]) to manually start up AngularJS application (for more information, see the Bootstrap guide).
See the following example:
// root-app
const rootApp = angular.module('root-app', ['app1', 'app2']);
// app1
const app1 = angular.module('app1', []);
app1.controller('main', function($scope) {
$scope.msg = 'App 1';
});
// app2
const app2 = angular.module('app2', []);
app2.controller('main', function($scope) {
$scope.msg = 'App 2';
});
// bootstrap
angular.bootstrap(document.querySelector('#app1'), ['app1']);
angular.bootstrap(document.querySelector('#app2'), ['app2']);
<!-- angularjs#1.7.0 -->
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.7.0/angular.min.js"></script>
<!-- root-app -->
<div ng-app="root-app">
<!-- app1 -->
<div id="app1">
<div ng-controller="main">
{{msg}}
</div>
</div>
<!-- app2 -->
<div id="app2">
<div ng-controller="main">
{{msg}}
</div>
</div>
</div>
<html>
<head>
<script src="angular.min.js"></script>
</head>
<body>
<div ng-app="shoppingCartParentModule" >
<div 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 ng-controller="NamesController">
<h1>List of Names</h1>
<div ng-repeat="name in names">
<p>{{name.username}}</p>
</div>
</div>
</div>
</body>
<script>
var shoppingCartModule = angular.module("shoppingCart", [])
shoppingCartModule.controller("ShoppingCartController",
function($scope) {
$scope.items = [
{product_name: "Product 1", price: 50},
{product_name: "Product 2", price: 20},
{product_name: "Product 3", price: 180}
];
$scope.remove = function(index) {
$scope.items.splice(index, 1);
}
}
);
var namesModule = angular.module("namesList", [])
namesModule.controller("NamesController",
function($scope) {
$scope.names = [
{username: "Nitin"},
{username: "Mukesh"}
];
}
);
angular.module("shoppingCartParentModule",["shoppingCart","namesList"])
</script>
</html>