angular JS adding and removing movie to a array of favorites - angularjs

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));
};

Related

React - Minified exception occurred in mvc

i want add some react.js components in ASP.NET mvc application. but react.js sometimes working and not working. i am using gulp-uglify in gulp.js
i have already try to set : dev environment
set NODE_ENV=development
but still I get that error in browser console.
#* React Library *#
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.6/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.6/react-dom.js"></script>
#* JSX parser library *#
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.min.js"></script>
<script src="/dom.jsx" type="text/babel"></script>
dom.jsx
var object;
var $item_url = "/item/";
var $c_url = "/category/";
var TemplateGrid = React.createClass({
render: function() {
return (
<div className="product-item column">
<span className="pin featured">Featured</span>
<div className="product-preview-actions">
<figure className="product-preview-image">
<img src="assets/images/items/flat_m.jpg" alt="product-image" />
</figure>
<div className="preview-actions">
<div className="preview-action">
<a href={$item_url + this.props.item.name}>
<div className="circle tiny primary">
<span className="icon-tag" />
</div>
</a>
<a href={$item_url + this.props.item.name}>
<p>Go to Item</p>
</a>
</div>
<div className="preview-action">
<a href={$item_url + this.props.item.name}>
<div className="circle tiny secondary">
<span className="icon-heart" />
</div>
</a>
<a href={$item_url + this.props.item.name}>
<p>Favourites +</p>
</a>
</div>
</div>
</div>
<div className="product-info">
<a href={$item_url + this.props.item.ProductId + "/" + (this.props.item.name).replace(/\s/g, "_")}>
<p className="text-header">{this.props.item.name}</p>
</a>
<p className="product-description"></p>
<a href={$c_url + this.props.item.Category}>
<p className="category primary">{this.props.item.Category}</p>
</a>
<p className="price"><span>$</span>12</p>
</div>
</div>
);
}
});
var Widgets = React.createClass({
getInitialState: function(){
return {
items: []
}
},
componentDidMount:function(){
$.get(this.props.dataUrl, function (data) {
object = data;
if(this.isMounted()){
this.setState({
items: data.tumb
});
}
}.bind(this));
},
componentDidUpdate: function () {
$(".slide-control.left,.slide-control.right").append('<svg class="svg-arrow"><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#svg-arrow"></use></svg>');
setTimeout(function () {
$('.owl-carousel').owlCarousel('refresh');
}, 1000);
},
render : function(){
var rows = [];
var left = [];
var right = [];
this.state.items.forEach(function (item) {
var i=0;
var o = object.objects[i]; i++;
document.getElementById('Thumb-title').innerText = o.name;
rows.push(<TemplateGrid key={item.ProductId} item={item} />);
});
return (
<div className="product-showcase">
<div className="headline primary">
<h4 id="Thumb-title" />
<div className="slide-control-wrap">
<div className="slide-control left">
</div>
<div className="slide-control right">
</div>
</div>
</div>
<div id="pl-1" className="product-list grid column4-wrap owl-carousel">
{rows}
</div>
</div>
);}
});
ReactDOM.render(
<Widgets dataUrl="/thumb/8/1" />,
document.getElementsByClassName('w1')
);

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.

Angularjs firebase ng-click loading values after two-three clicks

I have angularjs file
<div class="container starter-template">
<div class="col-md-9" >
<select ng-model="selectedName" ng-options="x as x.TeamName for x in teams" ng-change="selectedItemChanged()">
<option value="">Select Team</option>
</select>
</div>
<div class="col-md-3">{{date}} </div>
<hr>
<!-- <div ng-repeat="s in user">
<div ng-repeat="(key, value) in s">
{{selectedName.FirstName}} : {{value["Date"]}} {{value["TimeStamp"]}} {{value["Status"]}}
</div>
</div>-->
<div class="box box-default" style="width:1100px">
<div class="box-header with-border">
<h3 class="box-title">Employee Details </h3>
<div class="row" >
<br/>
<div class="col-lg-3 col-xs-6" ng-repeat="name in fullName">
<!-- small box -->
<div class="small-box bg-aqua" style="height:130px;width:150px;" >
<div class="inner">
<h3></h3>
</div>
<div class="icon">
<i class="ion ion-person" ></i>
</div>
<button ng-click="info(name)" class="btn btn-info btn-lg" data-toggle="modal" data-target="#myModal">More Info
<i class="fa fa-arrow-circle-right"></i>
</button><br/><br/>
<center><b><p >{{name}}</p></b></center>
</div>
<!-- Modal -->
<div class="modal fade" id="myModal" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">{{name}}</h4>
</div>
<div class="modal-body">
<p>Clock In : {{clock_in}}</p>
<p>Clock Out : {{clock_out}}</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="box box-default" style="width:1100px">
<div class="box-header with-border">
<h3 class="box-title">Clock In</h3>
<div class="row" >
</div>
</div>
</div>
<div class="box box-default" style="width:1100px">
<div class="box-header with-border">
<h3 class="box-title">Clock Out</h3>
<div class="row" >
</div>
</div>
</div>
<div id="inOut-container">FusionCharts will render here</div>
<div id="attendance-container">FusionCharts will render here</div>
</div>
and a javascript file:
app.controller('organization_drill_down', ['$scope', '$firebaseArray', '$firebaseObject', 'FBURL', function($scope, $firebaseArray, $firebaseObject, FBURL){
//current date
var today = new Date();
var dd = today.getDate();
var mm = today.getMonth()+1;
var yyyy = today.getFullYear();
if(dd<10){dd='0'+dd}
if(mm<10){mm='0'+mm}
$scope.date = dd+'/'+mm+'/'+yyyy;
$scope.all_ins = [];
$scope.all_outs = [];
var teams = new Firebase("************");
var time_stamps = new Firebase("*************") //collecting team's data
$scope.teams = $firebaseArray(teams); //teams for select dropdown
$scope.team = [];
$scope.uId = [];
$scope.in = 0;
$scope.out = 0;
$scope.selectedItemChanged = function() {
console.log($scope.selectedName.TeamName);
var ref = new Firebase("**************").orderByChild('TeamName')
.equalTo($scope.selectedName.TeamName) //check if selected team's name matches users
.on('value', function(snap) {
$scope.fullName = [];
$scope.user = snap.val();
angular.forEach($scope.user, function(user,user_key) {
$scope.fullName.push(user["FirstName"]+" "+user["LastName"]);
});
$scope.$digest();
});
};
//info on clicking more info for a specific user
$scope.info = function(name) {
var users = new Firebase("********************");
var name = name.split(" ");
console.log(name);
users.orderByChild('FirstName').equalTo(name[0]) //check if selected team's name matches users
.on('value', function(snap) {
$scope.user = snap.val();
angular.forEach($scope.user, function(user,user_key) {
if(user["LastName"] == name[1]) //checking if firstname and lastname are equal afterbutton click in user node
{
time_stamps.orderByKey()
.equalTo(user_key) //check if selected name's key is in timestamps
.on('value', function(snap) {
$scope.time_stamp = snap.val();
angular.forEach($scope.time_stamp, function(value, key) {
angular.forEach(value, function(value1, key) {
if(value[key]["Date"] == $scope.date ){
if(value[key]["Status"]== "In"){
$scope.all_ins.push(value[key]["TimeStamp"]);
}
else{
$scope.all_outs.push(value[key]["TimeStamp"]);
}
}
});
});
$scope.clock_in = $scope.all_ins[0];
$scope.clock_out = $scope.all_outs.pop();
});
}
});
$scope.$digest();
});
};
}]);
What I want is: on clicking the button "more info" should open a popup and call the function info(name) and return clock-in and clock out. But what is happening is, on clicking the button ng-click is hitting info(name) but after two-three clicks that is information is not loading directly. I am caught with such unusual error first time, can somebody help?
When clicking first time on button "more info":
after clicking second/third time on the button "more info":
Seems like (from what I could gather with identation and some observation) you are updating your variables outside of the users.orderByChild().equalTo().on part.
Firebase functions (like the one you used) are always promises and, in this case, the promise will end and then on('value', function(snap){ will run.
Since it is an async promise, you might be saving empty values to the variables you wanted to use in the modal. After trying a couple more times it ends up giving the promise enough time to execute so you get your correct values.
Also, bear in mind that using on will add a listener to that firebase node (on the condition of 'value' change) that will run whatever code you put inside it every time the condition is satisfied (not just the first time you call the code).

How to use controller as syntax in the following scenario

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>

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>

Resources