How to use controller as syntax in the following scenario - angularjs

controller as syntax problem
I am a newbie to angular, so please forgive me if i'm wrong. I have a problem where a service is used for certain operation. In this case, adding books to cart.
I have followed the recommended way using controller as syntax instead of $scope. But in kart-list.html, i'm not able to access kart details, since this operation is done by BookListCtrl.
app.js
var app = angular.module("app", ["ngRoute"]);
app.config(function($routeProvider) {
$routeProvider
.when("/books", {
templateUrl: "partials/book-list.html",
controller: "BookListCtrl",
controllerAs: 'booklist'
})
.when("/kart", {
templateUrl: "partials/kart-list.html",
controller: "KartListCtrl",
})
.otherwise({
redirectTo: "/books"
});
});
app.factory("kartService", function() {
var kart = [];
return {
getKart: function() {
return kart;
},
addToKart: function(book) {
kart.push(book);
},
buy: function(book) {
alert("Thanks for buying: ", book.name);
}
};
});
app.factory("bookService", function() {
var books = ['some data'];
return {
getBooks: function() {
return books;
},
addToKart: function(book) {
}
}
});
app.controller("KartListCtrl", function(kartService) {
var self = this;
self.kart = kartService.getKart();
self.buy = function(book) {
kartService.buy(book);
};
});
app.controller("HeaderCtrl", function() {
var self = this;
self.appDetails = {};
self.appDetails.title = "BooKart";
self.appDetails.tagline = "We have collection of 1 Million books";
});
app.controller("BookListCtrl", function(bookService, kartService) {
var self = this;
self.books = bookService.getBooks();
self.addToKart = function(book) {
kartService.addToKart(book);
};
});
book-list.html
<div id="bookListWrapper">
<form role="form">
<div class="form-group">
<input type="text" class="form-control" placeholder="Search here..." />
</div>
</form>
<ul class="list-unstyled">
<li class="book" ng-repeat="book in booklist.books" style="background: white url('imgs/{{book.imgUrl}}') no-repeat">
<div class="book-details clearfix">
<h3>{{book.name}}</h3>
<p>{{book.price}}</p>
<ul class="list-unstyled list-inline">
<li>Rating: {{book.rating}}</li>
<li>Binding: {{book.binding}}</li>
<li>Publisher: {{book.publisher}}</li>
<li>Released: {{book.releaseDate}}</li>
</ul>
<p>{{book.details}}</p>
<button class="btn btn-info pull-right" ng-click="addToKart(book)">Add to Kart</button>
</div>
</li>
</ul>
</div>
kart-view.html
<div id="bookListWrapper">
<p>Please click on buy button to buy the book.</p>
<ul class="list-unstyled">
<li class="book" ng-repeat="book in kart" style="background: white url('imgs/{{book.imgUrl}}') no-repeat">
<div class="book-details clearfix">
<h3>{{book.name}}</h3>
<p>{{book.price}}</p>
<ul class="list-unstyled list-inline">
<li>Rating: {{book.rating}}</li>
<li>Binding: {{book.binding}}</li>
<li>Publisher: {{book.publisher}}</li>
<li>Released: {{book.releaseDate}}</li>
</ul>
<p>{{book.details}}</p>
<button class="btn btn-info pull-right" ng-click="buy(book)">Buy</button>
</div>
</li>
</ul>
</div>
Problem is how use controller as syntax for kart-list.html near ng-repeat to access kart details?

Your'e using the controller as feature but you haven't covered all view references.
book-list.html
<button ... ng-click="addToKart(book)">Add to Kart</button>
Change to
<button ... ng-click="booklist.addToKart(book)">Add to Kart</button>
kart-view.html
<li ... ng-repeat="book in kart" ...
...
<button ... ng-click="buy(book)">Buy</button>
Change to
<li ... ng-repeat="book in KartListCtrl.kart" ...
...
<button ... ng-click="KartListCtrl.buy(book)">Buy</button>

You have to prefix booklist while calling addToKart() method in book-list.html.
Use below file which will resolve your issue:
book-list.html
<div id="bookListWrapper">
<form role="form">
<div class="form-group">
<input type="text" class="form-control" placeholder="Search here..." />
</div>
</form>
<ul class="list-unstyled">
<li class="book" ng-repeat="book in booklist.books" style="background: white url('imgs/{{book.imgUrl}}') no-repeat">
<div class="book-details clearfix">
<h3>{{book.name}}</h3>
<p>{{book.price}}</p>
<ul class="list-unstyled list-inline">
<li>Rating: {{book.rating}}</li>
<li>Binding: {{book.binding}}</li>
<li>Publisher: {{book.publisher}}</li>
<li>Released: {{book.releaseDate}}</li>
</ul>
<p>{{book.details}}</p>
<button class="btn btn-info pull-right" ng-click="booklist.addToKart(book)">Add to Kart</button>
</div>
</li>
</ul>
</div>

Related

angular JS adding and removing movie to a array of favorites

I'm quite new to angular js and I am having a hard time trying to implement a function who adds a movie to an array of favorites and removes it from the array in case it's already there (difficult part).
Those are my controllers bellow. The SearchController and DetailsController refer to the search.html and details.html respectively, also bellow. Can I get any help?
Thanks in advance
var myControllers = angular.module("myControllers", []);
myControllers.controller(
"SearchController",
function MyController($scope, $http) {
$scope.searchByTitle = function (title) {
$http
.get("http://www.omdbapi.com/?apikey=d4458e16&s=" + title)
.then(function (data) {
$scope.movies = data.data.Search;
});
};
$scope.wishlist = JSON.parse(localStorage.getItem("wishlist"));
}
);
myControllers.controller(
"DetailsController",
function MyController($scope, $http, $routeParams) {
$http
.get("http://www.omdbapi.com/?apikey=d4458e16&i=" + $routeParams.itemId)
.then(function (data) {
$scope.movies = data.data;
});
$scope.favList = JSON.parse(localStorage.getItem("wishlist")) || [];
$scope.isFavorite = false; //JSON.parse(localStorage.getItem("isFavorite")) || false;
$scope.addMovieToFavList = function (item) {
/*if ($scope.favList.includes(item)) {
console.log("movie is on favorites and will be removed");
//$scope.favList.pop(item);
} else {
console.log("movie is not on favorites and will be added");
//$scope.favList.push(item);
}*/
!$scope.isFavorite ? $scope.favList.push(item) : $scope.favList.pop();
$scope.isFavorite = !$scope.isFavorite;
localStorage.setItem("wishlist", JSON.stringify($scope.favList));
//localStorage.setItem("isFavorite", JSON.stringify($scope.isFavorite));
};
}
);
search.html:
<div class="container-fluid">
<h1>Film App<h1>
<div class="row">
<h2>Search</h2>
<input
ng-model="title"
class="form-control"
placeholder="Search for a film"
value="Search"
/>
<button ng-click="searchByTitle(title)" class="btn btn-primary btn-block">
Search for a movie
</button>
<ul class="list-group">
<li ng-repeat="movie in movies | filter:title" class="list-group-item">
<a href="#!/details/{{movie.imdbID}}">
<img ng-src="{{movie.Poster}}" width="30px" />
{{movie.Title}}<span>, {{movie.Year}}</span>
</a>
</li>
</ul>
</div>
</div>
<div class="container-fluid">
<h1>My Favorites<h1>
<ul class="list-group">
<li ng-repeat="favouriteMovie in wishlist" class="list-group-item">
<a href="#!/details/{{favouriteMovie.imdbID}}">
<img ng-src="{{favouriteMovie.Poster}}" width="30px" />
{{favouriteMovie.Title}}<span>, {{favouriteMovie.Year}}</span>
</a>
</li>
</ul>
</div>
details.html:
<div class="container">
<div class="row">
<div class="col-12 mt-3">
<div class="card" ng-model="movies">
<div
class="card-header d-flex align-items-start justify-content-between"
>
<a href="#!">
<button>Back Home</button>
</a>
<button ng-click="addMovieToFavList(movies)">
{{isFavorite==false?'Add to favorites':'Remove from favorites'}}
</button>
<h1 class="card-title my-0">{{movies.Title}}</h1>
<img ng-src="{{movies.Poster}}" />
</div>
<div class="card-body">
<div class="card-text text-secondary">
<h4>Year</h4>
<p>{{movies.Year}}</p>
<h4>Cast</h4>
<p>{{movies.Actors}}</p>
<h4>Plot</h4>
<p>{{movies.Plot}}</p>
<h4>Rating</h4>
<p>{{movies.imdbRating}}/10</p>
</div>
</div>
</div>
</div>
</div>
</div>
You will want to check for the movie via an identifier (like an ID) not by comparing whole objects. So, assuming the object has a property called 'ID' we can check for that. Also, to remove an item from your array, you can use splice
$scope.addMovieToFavList = function(item) {
let index = $scope.favList.findIndex(movie => movie.ID == item.ID);
if (index === -1) {
// movie doesn't exist in favorites yet
$scope.favList.push(item)
$scope.isFavorite = true;
} else {
// movie exists, we will splice it out
$scope.favList.splice(index, 1)
$scope.isFavorite = false
}
localStorage.setItem("wishlist", JSON.stringify($scope.favList));
};

AngularJS Variable in service is not updating in view?

I have spent a couple of days banging my head against the table, reading blog posts, and SO questions around my issue. I tried several variations of the code I have below and none has worked so far. I would appreciate any help.
The taskList variable inside the service does update, but the one in the controller does not.
Controller
angular.module("TaskManager").controller("mainController", function ($scope, API) {
$scope.init = function () {
console.log("Initializing app");
API.getTasks();
}
$scope.tasks = API.taskList;
$scope.$watch(function(){return API.taskList}, function(newVal, oldVal){
alert("This is tasklist in controller" + newVal);
}, true)
});
Service
angular.module("TaskManager").service("API", function ($http, $rootScope) {
const apiKey = "PUH";
var taskList = [1,2,3,4];
const getTasks = function () {
$http.get("https://api.mlab.com/api/1/databases/jquerytaskmanager/collections/tasks?apiKey=" + apiKey).then(function (data) {
taskList = data;
console.log(taskList);
});
};
$rootScope.$watch(function(){return taskList}, function(newVal, oldVal){
alert(taskList);
taskList = newVal;
console.log(taskList);
}, true)
return {
getTasks,
taskList
}
});
View
<div class="row">
<div class="col s12">
<ul id="mainMenu" class="right hide-on-med-and-down">
<li><a class="waves-effect waves-light btn blue darken-4"><i class="fa fa-bars" aria-hidden="true"></i> Menu</a></li>
<li><a class="waves-effect waves-light btn blue darken-4"><i class="fa fa-plus" aria-hidden="true"></i> Add Task</a></li>
<li><a class="waves-effect waves-light btn blue darken-4"><i class="fa fa-pencil" aria-hidden="true"></i> Manage Categories</a></li>
</ul>
</div>
</div>
<div class="mainContainer container">
<div class="row">
<div class="col 6">
<h2>Tasks</h2>
</div>
</div>
<ul>
<li class="taskContainer" ng-repeat="task in tasks" >
<div class="row">
<div class="col s6">
<span class="taskName"> {{task.task_name}}</span>
</div>
<div class="col s6">
<button class="btn blue darken-4 waves-effect waves-light ">Edit</button> <button class="btn red darken-4 waves-effect waves-light ">Delete</button>
</div>
</div>
</li>
</ul>
</div>
Return the $http promise from the service:
app.service("API", function($http) {
this.getTasks = function() {
return $http.get(url);
};
});
Then in the controller, extract the data from the promise:
app.controller("mainController", function($scope, API) {
this.$onInit = function () {
console.log("Initializing app");
API.getTasks().then(function(response) {
$scope.tasks = response.data;
});
};
});
For more information, see AngularJS $http Service API Reference.

Add to cart using angular js

I want to create the shopping cart using angular js.And i am new to angular js.My question is how to use cart functionality As of now i displayed the products list using REST API
<div class="col-sm-2" ng-repeat="product in productdata">
<div class="col-item">
<div class="photo">
<a ng-href="#/productdesc">
<img src="{{product.imageUrl}}" class="img-responsive" alt="a" />
</a>
</div>
<div class="info">
<div class="row">
<div class="col-md-12">
<h5>{{product.productname}}-{{product.id}}</h5>
<h5 class="price-text-color">${{product.price}}</h5>
</div>
</div>
<div class="separator clear-left">
<p class="btn-add">
<input type="number" value="1" class="form-control text-center" min="1">
</p>
<p class="btn-details">
<a href="#" class="hidden-sm btn btn-group-sm btn-primary">
<i class="fa fa-shopping-cart"></i>Add
</a>
</p>
</div>
<div class="clearfix"></div>
</div>
</div>
</div>
And i need to know how the values will be saved as cookies or session in browser.
You could use localStorage or sessionStorage to save you shppping cart data.
For example you could use a package like angular-local-storage for working with sessionStorage in a AngularJS app.
UPDATE:
Disclaimer: I didn't tested this code! Is only a sample code to show you the way that you could follow. Good luck! :)
In your app config:
myApp.config(function (localStorageServiceProvider) {
localStorageServiceProvider
.setPrefix('yourAppName');
localStorageServiceProvider
.setStorageType('sessionStorage');
});
Service:
myApp.factory('CartProduct', function(localStorageService) {
var cartProducts = [];
function init() {
if (localStorageService.get('cart-products').length) {
cartProducts = localStorageService.get('cart-products');
}
}
init();
function getAll() {
return cartProducts;
}
function add(product) {
cartProducts.push(product);
localStorageService.set('cart-products', cartProducts);
}
return {
add: add,
getAll: getAll
};
});
Controller:
myApp.controller('MyCtrl', function($scope, CartProduct) {
$scope.addToCart = function (product) {
CartProduct.add(product);
}
});
HTML:
<div class="separator clear-left">
<p class="btn-add">
<input type="number" ng-model="product.quantity" value="1" class="form-control text-center" min="1">
</p>
<p class="btn-details">
<a href="#" ng-click="addTocart(product)" class="hidden-sm btn btn-group-sm btn-primary">
<i class="fa fa-shopping-cart"></i>Add
</a>
</p>
</div>

AngularJS Factory and Parse.com User Authentication

I am playing around with AngularJS using Parse.com as it's backend and am having an issue when I try go authenticate and deuthenticate with Parse. I am abe to do both these functions, but my views don't update.
app.factory('hsUser', ['$http', function($http){
var dataObject = null;
return {
get: function()
{
var tmpData = Parse.User.current();
console.log(tmpData);
if(tmpData && dataObject == null)
{
dataObject = {};
keys = Object.keys(tmpData);
keys.forEach(function(value)
{
dataObject[value] = tmpData[value];
});
console.log(dataObject);
}
return dataObject;
},
authenticate: function(username, password)
{
console.log('auth');
Parse.User.logIn(username, password, {
success: function(userData) {
dataObject = {};
keys = Object.keys(userData);
keys.forEach(function(value)
{
dataObject[value] = userData[value];
});
},
error: function(userData, errorData) {
console.log(errorData);
}
});
},
deauthenticate: function()
{
Parse.User.logOut();
dataObject = Parse.User.current();
},
doRegister: function(registration)
{
console.log(registration);
return {
success: true
}
}
}
}]);
Here are my controllers.
app.controller('HeaderController', ['hsConfig','hsUser', function( hsConfig, hsUser)
{
this.config = hsConfig.get();
this.user = hsUser.get();
}]);
app.controller('AuthController', ['hsUser', function( hsUser)
{
this.user = hsUser.get();
this.authUser = {
emailAddress: "testinguser",
password: "testinguser",
remember: false,
}
this.authenticate = function()
{
hsUser.authenticate(this.authUser.emailAddress, this.authUser.password);
}
this.deauthenticate = function()
{
this.user = hsUser.deauthenticate();
console.log('Deauthenticated')
}
}]);
Here is the HTML for the directive that creates the navbar
<div class="header" ng-controller="HeaderController as headCtrl">
<nav class="navbar navbar-default">
<div class="container-fluid">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
<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="/">{{ headCtrl.config.brand }}</a>
</div>
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav navbar-right" ng-hide="headCtrl.user">
<li class="dropdown" ng-controller="AuthController as authCtrl">
<a class="dropdown-toggle" href data-toggle="dropdown">
Sign In
<strong class="caret"></strong>
</a>
<div class="dropdown-menu auth-form-container" style="padding: 15px; padding-bottom: 0px;" >
<form role="form" ng-submit="authCtrl.authenticate();">
<div class="form-group">
<label for="exampleInputEmail1">Email address</label>
<input type="email" class="form-control" placeholder="Enter email" ng-model="authCtrl.authUser.emailAddress" >
</div>
<div class="form-group">
<label for="exampleInputPassword1">Password</label>
<input type="password" class="form-control" placeholder="Password" ng-model="authCtrl.authUser.password">
</div>
<div class="form-group checkbox">
<label>
<input type="checkbox" ng-model="authCtrl.authUser.remember"> Remember Me
</label>
</div>
<div class="form-group">
<button class="btn btn-primary btn-full">Sign In</button>
</div>
</form>
</div>
</li>
<li class="divider-vertical"></li>
<li>Register</li>
</ul>
<ul class="nav navbar-nav navbar-right" ng-show="headCtrl.user">
<li>Profile</li>
<li class="divider-vertical"></li>
<li ng-controller="AuthController as authCtrl">
<a href ng-click="authCtrl.deauthenticate();">Sign Out</a>
</li>
</ul>
</div>
</div>
</nav>
</div>
The entire project including Parse keys can be found here. I'll delete the keys once I figure out wtf my problem is.
https://github.com/thenetimp/hackerspace
If anyone can point me into what I am doing wrong and explain it so I can understand what I need to do with other Models I would greatly appreciate it.
whenever you update the model outside of angulars context, I.e in the callback of a promise, you need to use $scope.apply to notify angular.

Closing all open Bootstrap modals in AngularJS?

I have created a modal that opens another modal. I want to use the second modal as a confirmation box to close the first one. I cant get it to close both modals when I click ok on the confirmation box (the second modal).
Tree.html:
<script type="text/ng-template" id="tree_item_renderer.html">
<div class="bracket-match" ng-class="match.tier == 1 ? 'bracket-match-final' : ''">
<p ng-show="match.tier == 1" class="finale-title">Finale</p>
<div class="match-content">
<div class="player-div">
<div class="bracket-player-1 bracket-player-1-tier-{{tierCount+1-match.tier}}">
<input class="input-player-1 input-player-name form-control" type="text" ng-model="match.player1" placeholder="Deltager 1">
</div>
</div>
<div class="player-div border-bottom">
<div class="bracket-player-2">
<input class="input-player-2 input-player-name form-control" type="text" ng-model="match.player2" placeholder="Deltager 2">
</div>
</div>
</div>
<div ng-show="match.tier == 1 && showthirdplace && tierCount >= 2" class="third-place" ng-model="thirdplace">
<p class="finale-title">3. plads</p>
<div class="match-content">
<div class="player-div">
<div class="bracket-player-1 bracket-player-1-tier-{{tierCount+1-match.tier}}">
<input class="input-player-1 input-player-name form-control" type="text" ng-model="match.player1" placeholder="Deltager 1">
</div>
</div>
<div class="player-div border-bottom">
<div class="bracket-player-2">
<input class="input-player-2 input-player-name form-control" type="text" ng-model="match.player2" placeholder="Deltager 2">
</div>
</div>
</div>
</div>
</div>
<div class="bracket-column">
<div ng-repeat="match in match.previousMatches" ng-include="'tree_item_renderer.html'" />
</div>
</script>
<script type="text/ng-template" id="tournament-tree.html">
<div class="row modal-footer-btns">
<button class="btn btn-primary" ng-click="ok()">GEM</button>
<button class="btn btn-warning btn-xs" ng-click="openAlertBox()" type="button" data-dismiss="modal">LUK, uden at gemme</button>
</div>
<div class="row" style="margin-bottom:15px;">
<a ng-click="addMatchTier()" class="btn btn-primary"><i class="glyphicon glyphicon-plus"></i></a>
<a ng-click="removeMatchTier()" ng-class="tierCount > 1 ? 'btn btn-primary' : 'btn btn-default'"><i class="glyphicon glyphicon-minus"></i></a><br />
</div>
<div class="row tournament-tree">
<div ng-repeat="match in finalMatch">
</div>
<div class="bracket-column">
<div ng-repeat="match in finalMatch" ng-include="'tree_item_renderer.html'"></div>
</div>
</div>
</script>
<script type="text/ng-template" id="openAlertBox.html">
<div class="modal-header">
<h3 class="modal-title"></h3>
</div>
<div class="modal-body"> </div>
<div class="modal-footer">
<button class="btn btn-primary" ng-click="ok()">Ja</button>
<button class="btn btn-warning" ng-click="cancel()">Annuller</button>
</div>
</script>
Categories.html:
<div class="row">
<div class="modal-header">
<h3 class="modal-title"></h3>
</div>
</div>
<div ng-controller="CategoriesController">
<a ng-click="add()" class="btn btn-tree btn-primary" style="margin-top:15px;">Tilføj hovedkategori</a>
<p ng-repeat="data in nodes" ng-include="'category_item_renderer.html'"></p>
<ng-include src="'Modules/TournamentTree/Tree.html'"></ng-include>
</div>
<script type="text/ng-template" id="category_item_renderer.html">
<div class="category-style">
<div class="push-cat-btn">
<a ng-click="add(data)" class="btn btn-primary btn-sm"><i class="glyphicon glyphicon glyphicon-plus"></i></a>
<a ng-hide="data.nodes.push()" ng-click="openTournamentTree(data)" class="btn btn-info btn-xs">Turnering</a>
</div>
</div>
<p class="push" ng-repeat="data in data.nodes" ng-include="'category_item_renderer.html'"></p>
</script>
<script type="text/ng-template" id="TournamentTreeModal.html">
<div class="modal-header">
<h3 class="modal-title"></h3>
</div>
<div class="modal-body">
<div class="include-tree" ng-include="'tournament-tree.html'"></div>
</div>
<div class="modal-footer">
</div>
</script>
TreeController.js:
angular.module('tournamentTree', ['ui.bootstrap']);
angular.module('tournamentTree').controller("TreeController", ['$scope', '$modal', '$modalInstance', 'guidGenerator', function ($scope, $modal, $modalInstance, guidGenerator) {
$scope.openAlertBox = function () {
var alertBoxInstance = $modal.open({
templateUrl: 'openAlertBox.html',
controller: 'TreeController',
scope: $scope,
size: 'xs',
resolve: {
}
});
};
$scope.ok = function () {
$scope.close();
$scope.$parent.close();
}
$scope.cancel = function () {
$scope.close();
$scope.$parent.dismiss('cancel');
};
categoriController.js:
angular.module('tournamentCategories').controller("CategoriesController",
['$scope', '$modal', 'guidGenerator', 'eventBus', domainName + "Service", 'TournamentCategoryModelFactory',
function ($scope, $modal, guidGenerator, eventBus, domainService, modelFactory) {
$scope.openTournamentTree = function () {
var modalInstance = $modal.open({
templateUrl: 'TournamentTreeModal.html',
controller: 'TreeController',
scope: $scope,
size: 'wide-90',
backdrop: 'static',
keyboard: false,
resolve: {
}
});
modalInstance.result.then(function (selectedItem) {
//$scope.selected = selectedItem;
}, function () {
//$log.info('Modal dismissed at: ' + new Date());
});
};
}]);
You can use $modalStack from ui.bootstrap to close all instances of $modalInstance
$modalStack.dismissAll(reason);
This is how i got it working in my project without using any factory or additional code.
//hide any open bootstrap modals
angular.element('.inmodal').hide();
I have a timeout function that emits logout as $rootScope.$emit('logout'); and the listener in my service is as follows:
$rootScope.$on('logout', function () {
//hide any open bootstrap modals
angular.element('.inmodal').hide();
//do something else here
});
If you want to hide any other modals such as angular material dialog ($mdDialog) & sweet alert dialog's use angular.element('.modal-dialog').hide(); & angular.element('.sweet-alert').hide();
I don't know if this is the right approach , but it works for me.

Resources