Can't display ng-repeat child scope property - angularjs

I need to display a list of data records using ng-repeat. Within every data object entry (a coupon) displyed, I need to grab some properties ($scope.etabName and $scope.etabDistance) from that object, do some calculations and show the result in the same data object's view within the ng-repeat view.
I've managed to do the calculations and when I console.log them the results are correct, but they are not showing correctly: the property displyed is the one relative to the last data object iterated by ng-repeat.
I know I'm not understanding the Angular way of doing scopes, so any help is welcome.
My controller:
$scope.getCouponList = function () {
$http({
method: 'JSONP',
url: $scope.couponListUrl + "?callback=JSON_CALLBACK&cookie=" + $localStorage.user.cookie +
"&usr_latitude=" + $rootScope.lat + "&usr_longitude=" + $rootScope.lng
}).
success(function (data, status) {
if (data.status && data.status == "ok") {
$rootScope.couponList = data.list;
}
}).error(function (data, status, headers, config) {
});
$scope.fetchEtabDetails = function($stateParams) {
_.select($stateParams.etablissement, function (etab) {
if (etab.id === $stateParams.etabcloser) {
$scope.etabName = etab.name;
$scope.etabDistance = etab.distance;
}
});
};
};
My view:
<ion-content scroll="true" ng-controller="getCouponList">
<ion-list>
<ion-item class="decline" ng-repeat="coupon in couponList"
ng-click="fetchCouponDetails(coupon)"
ng-init="fetchEtabDetails(coupon)">
<div class="offer-image">
<img class="full-image" ng-src="{{coupon.image_operation}}">
<div class="offer-logo">
<img ng-src="{{coupon.enseigne_logo_url}}">
</div>
<div class="offer-ens-name">
<span>{{coupon.ens_name}}</span>
</div>
<div class="offer-name wrap-txt">
<span>{{coupon.name}}</span>
</div>
<div class="offer-deadline-details">
<i class="icon ion-android-time"></i>
<timer countdown="coupon.diff_date" max-time-unit="'year'" interval="1000">{{ddays}}:{{hhours}}:{{mminutes}}</timer>
</div>
<div class="offer-zone">
<i class="icon ion-location" class="etab"></i>
<span>{{etabName}} {{etabDistance}} km</span>
</div>
</div>
</ion-item>
</ion-list>
</ion-content>

In this function:
$scope.fetchEtabDetails = function($stateParams) {
_.select($stateParams.etablissement, function (etab) {
if (etab.id === $stateParams.etabcloser) {
$scope.etabName = etab.name;
$scope.etabDistance = etab.distance;
}
});
You only have 1 $scope.etabName. Each call is overwriting it.
I would do this...
$scope.fetchEtabDetails = function($stateParams) {
_.select($stateParams.etablissement, function (etab) {
if (etab.id === $stateParams.etabcloser) {
$stateParams.etabName = etab.name;
$stateParams.etabDistance = etab.distance;
}
});
then in your HTML...
<div class="offer-zone">
<i class="icon ion-location" class="etab"></i>
<span>{{coupon.etabName}} {{coupon.etabDistance}} km</span>
</div>

Related

AngularJS toggle ng source value on click

I need some help about toggling ng-src between for example: image.jpg and image-active.jpg, but I have some issues because I need to active that with AngularJS.
This is the scenario: I called an API data from swagger and use ng-repeat to display images in html.
HTML
<div class="input-group interests-list">
<div class="checkbox" ng-repeat="interest in interests">
<label>
<div class="interest-icon">
<img src="{{interest.iconUrl}}" ng-click="changeImage()">
</div>
<input style="display: none;" type="checkbox" value="{{interest.name}}">
{{interest.name}}
</label>
</div>
</div>
Service
this.getInterests = function () {
var deferred = $q.defer();
var req = {
method: 'get',
url: 'http://customdealwebapi20180125110644.azurewebsites.net/api/Interests'
}
$http(req).then(function (response) {
deferred.resolve(response.data);
}, function (err) {
console.log(err)
});
return deferred.promise;
}
Controller
TestService.getInterests().then(function (data) {
$scope.interests = data;
});
and everything works fine
Now I want to achieve when someone click on the image, ng-src should be changed to image-active.jpg, and on the next click image should be changed to default value (image.jpg)
I know how to achieve through jQuery, like this
$(".interests-list .checkbox label input[type='checkbox']").change(function () {
var selectedIcon = $(this).val();
if (this.checked) {
console.log($(this).prev())
$(this).prev().find("img").attr("src", "assets/img/home/icons/" + selectedIcon + "-active.png");
} else {
$(this).prev().find("img").attr("src", "assets/img/home/icons/" + selectedIcon + ".png");
}
});
Thank you
You can either use ng-show
<div class="checkbox" ng-repeat="interest in interests" ng-init="interest.active = false">
<label>
<div class="interest-icon">
<img ng-show="interest.active == true" src="active.png" ng-click="interest.active = !interest.active">
<img ng-show="interest.active == false" src="other.png" ng-click="interest.active = !interest.active">
</div>
</label>
</div>
or you can pass interest to your click function and set image src in your controller
<img src="{{interest.iconUrl}}" ng-click="changeImage(interest)">
$scope.changeImage = function(interest){
if(checked)
interest.iconUrl = "active.png";
else
interest.iconUrl = "other.png";
}

How to hide an element while using a directive?

I have made a directive in which a single template is using for three functions in a controller. The model for the fields are same. I want to hide a field if the directive is called third time.
<div class="active tab-pane " ng-if="linkid === '1'">
<mallsonline-product info="active_products"></mallsonline-product>
</div>
<!--Active products list ends here -->
<!-- Get Inactive Products -->
<div class="active tab-pane" ng-if="linkid === '2'" >
<mallsonline-product info="inactive_products"></mallsonline-product>
</div>
<!--Get most viewed products ends here -->
<div class="active tab-pane" ng-if="linkid === '3'" >
<mallsonline-product info="mostviewed_products"></mallsonline-product>
</div>
My controller looks something like this
mainControllers.controller('DashboardController', ['$scope', '$http', '$routeParams', '$cookies', '$rootScope', function ($scope, $http, $routeParams, $cookies, $rootScope) {
/* Getting all grid links */
$scope.grLinks = function (Id) {
console.log(Id);
$scope.linkid = Id;
};
/* Getting all grid links ends here */
/* Getting all active product list */
$scope.active_product = function () {
$http.get('js/active-products.json',
{headers:
{'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': $rootScope.keyword_auth_token}
})
.success(function (data) {
$scope.active_products = data.items;
console.log($scope.active_products);
})
.error(function (data) {
console.log(data);
});
};
/* Getting all active product ends here */
/* Getting all inactive product */
$scope.inactive_product = function () {
$http.get('js/inactive-products.json',
{headers:
{'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': $rootScope.keyword_auth_token}
})
.success(function (data) {
$scope.inactive_products = data.items;
console.log($scope.inactive_products);
})
.error(function (data) {
console.log(data);
});
};
/* Getting all inactive product */
/* Getting all most viewed products */
$scope.most_viewed = function () {
$http.get('js/most-viewed.json',
{headers:
{'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': $rootScope.keyword_auth_token}
})
.success(function (data) {
$scope.mostviewed_products = data.items;
console.log($scope.mostviewed_products);
})
.error(function (data) {
console.log(data);
});
};
/* Getting all most viewed products */
$scope.active_product();
$scope.inactive_product();
$scope.most_viewed();
}]);
/* Active products / Inactive and most viewed Directive */
mainControllers.directive('mallsonlineProduct', function () {
return {
restrict: 'E',
scope: {
productInfo: '=info'
},
templateUrl: 'directives/dashboard_product.html'
};
});
/* Active products / Inactive directive ends here*/
and the template looks like this
<li class="bord-1-solid-ccc mg-bt-25" ng-repeat="active_products in productInfo">
<article class="aa-properties-item mg-top-0-notimp">
<a class="aa-properties-item-img" href="#/product">
<img alt="img" class="twohun-oneseventy" src="img/item/6.jpg">
</a>
<div class="aa-properties-item-content">
<div class="aa-properties-about padding-0-notimp">
<h5>{{active_products.name}}</h5>
<p class="font-size-11-imp"><i class="fa fa-building-o" aria-hidden="true"></i> {{active_products.mall.name}}</p>
<p class="font-size-11-imp"><i class="fa fa-map-marker" aria-hidden="true"></i> {{active_products.mall.address}}</p>
<p class="font-size-11-imp"><i class="fa fa-phone" aria-hidden="true"></i> {{active_products.shop.telephone}}</p>
<p class="font-size-11-imp"><i class="fa fa-eye" aria-hidden="true"></i> {{active_products.views}}</p>
</div>
</div>
</article>
</li>
all the fields are present in the model I want to show the active_products.view only when info="mostviewed_products". How can I achieve this ?
Had passed "linkid" in directive to know the current linkid value in template
Please make following changes
Directive
mainControllers.directive('mallsonlineProduct', function () {
return {
restrict: 'E',
scope: {
productInfo: '=info',
linkid:'=linkid'
},
templateUrl: 'directives/dashboard_product.html'
};
});
Html
<div class="active tab-pane " ng-if="linkid === '1'">
<mallsonline-product info="active_products" linkid="linkid"></mallsonline-product>
</div>
<!--Active products list ends here -->
<!-- Get Inactive Products -->
<div class="active tab-pane" ng-if="linkid === '2'" >
<mallsonline-product info="inactive_products" linkid="linkid"></mallsonline-product>
</div>
<!--Get most viewed products ends here -->
<div class="active tab-pane" ng-if="linkid === '3'" >
<mallsonline-product info="mostviewed_products" linkid="linkid"></mallsonline-product>
</div>
In template ('directives/dashboard_product.html')
<p class="font-size-11-imp"><i class="fa fa-eye" aria-hidden="true" ng-if="linkid==3"></i> {{active_products.views}}</p>
Hope this will resolve your issue.

Not able to fetch data after refreshing dynamically created url in angular js application

I am new to angularjs and this my first post to stackoverflow. Iam trying to create small part of existing angular.
Iam trying to fetch dynamic url for "allproducts" page where url will have /allproducts/{corresponding city id}
My App.js looks like this:
myApp.config(function ($routeProvider) {
$routeProvider
.when('/',
{
templateUrl: "view"
})
.when('/Cities',
{
templateUrl: "cities"
})
.when('/products',
{
templateUrl: "view/cities_products"
})
.when('/allproducts/:id',
{
templateUrl: "city/{id}/products"
})
.otherwise({
template: 'NOT FOUND'
})
});
and rest is defined inside a controller. This is to get city data
httpService.get(get_data_url3,"")
.then(function (result) {
if (result.status == 200) {
$scope.cities_data=result.data.data;
console.log($scope.cities_data);
}
if (result.status == 404) {
console.log("unauthorised");
}
}, function (status) {
console.log(status);
});
This is to get product data on click of corresponding city
$scope.allCityProducts = function(city,path)
{
$location.path('/allproducts/'+city.id);
var get_products_url=initial_url+"products/"+city.id;
$scope.selected_city=city;
httpService.get(get_products_url,"")
.then(function (result) {
if (result.status == 200) {
$scope.product_data=result.data;
}
if (result.status == 404) {
console.log("unauthorised");
}
}, function (status) {
console.log(status);
});
}
And html code for cities is below on whose click dynamic product url is being fetchd
<div class="view_context">
<br>
<div class="row table-heading">
<div class="column medium-4">Cities <i class="fa fa-map-marker"></i></div>
<div class="column medium-4">View Products <i class="fa fa-star"></i></div>
<div class="column medium-4"></div>
</div>
<div class="table-inside column medium-12" ng-repeat="city in cities_data">
<div class="column medium-4"> {{city.city_name}}</div>
<div class="column medium-4"><a style="color:black;" ng-click="allCityProducts(city,path)"><i class="fa fa-share-square" style="margin-right:10px"></i>VIEW</a></div>
<div class="column medium-4"></div>
</div>
and the product page is below
<div class="table-inside table-white column medium-12">
<div class="column medium-4">{{prod.product_name}}</div>
<div class="column medium-3">{{prod.product_price_city | currency:"₹ "}}</div>
<div class="column medium-3"><a style="color:black;" data-reveal-id="productModal" ng-click="editproduct(prod)"><i class="fa fa-pencil-square"></i> VIEW/EDIT</a></div>
<div class="column medium-2"><i class="fa fa-trash" ng-click="deleteproduct(prod,selected_city.id,$index)"></i></div>
</div>
All works well except when dynamically created product page is reloaded no data is being fetched because httpservice is working on ng-click="allcityproducts". where city id is passed. What can be done to sort this??
For fetching a template based on the city id ,you could have templateUrl function instead of using URL string directly. templateUrl function will have 1st parameter(here its params) which will have route parameter object.
Code
templateUrl: function(params){
return "city/"+ params.id +"/products"
}

Function automatically called in some condition

I have code like this:
<div class="row"
ng-repeat="x in companies|orderBy:'id' ">
<div class="col left" >
<button ng-click="viewPublicId(x.id)">{{x.companyname}}</button>
</div>
<div class="col left">
{{x.address}}
</div>
<div class="col left">
{{x.telephone}}
</div>
</div>
What I want to do is add a check: when companies.size=1, function viewPublicId is automatically called. How can I achieve that? Thanks.
updated: viewPublicId function:
$scope.viewPublicId = function viewPublicId(companyid) {
var url = "http://7cf8d64c.tunnel.mobi/yii2-basic/web/index.php?r=restpublic/view&companyid=" + companyid;
console.log("debug", url);
$http.get(url)
.success(function (response)
{
console.log("debug PublicId",response);
if(response.length==33)
$scope.publicids = null;
else
$scope.publicids = response;
})
.error(function (response)
{
console.log("debug PublicId",response);
$scope.publicids = null;
});
$state.go('tabs.publicidlist');
}
In you controller:
if ($scope.companies.length === 1) {
$scope.viewPublicId();
}
If your companies could be changed dynamically, and you need to call the function everytime it changes, use $watch:
$scope.$watch('companies', function () {
if ($scope.companies.length === 1) {
$scope.viewPublicId();
}
}, true);

How to query parse.com users through factory Service in AngularJS?

Building an cross-platform hybrid app using Parse.com, AngularJS using the Ionic Framework. The user creation and querying works fine when using the simple parse.com code from the docs.
However I have been trying to put the query into a AngularJS service, so that it can be accesses and I can do a ng-repeat to display the returned results in a list.
The code put in place so far is this:
View (search.html):
<div class="row">
<div class="col col-75">
<label class="item item-input">
<i class="icon ion-search placeholder-icon"></i>
<input type="text" placeholder="Search" ng-model="search.queryvalue">
</label>
</div>
<div class="col">
<button class="button button-calm" ng-click="searchnow()">Search</button>
</div>
</div>
<ion-list>
<ion-item class="item-avatar" type="item-text-wrap" ng-repeat="user in users">
<img ng-src="{{userpic}}.png">
<h2>{{user.id}}</h2>
<p>{{user.get('location')}}</p>
</ion-item>
</ion-list>
Controller:
.controller('SearchCtrl', function($scope, $state, $rootScope, parseQueryFactory) {
$scope.search = {};
$scope.users = {};
$scope.searchnow = function () {
$scope.users = parseQueryFactory.searchUsers($scope.search.queryvalue);
};
})
Services:
.factory('parseQueryFactory', function($http) {
var query = new Parse.Query(Parse.User);
var people = {};
return {
searchUsers: function(searchVal){
query.startsWith("username", searchVal); // Search username
query.limit(20);
return query.find({
success: function(people) {
/*var objects = {};
for (var i = 0; i < people.length; i++) {
var object = people[i];
objects = objects + object;
}
console.log(people);
return objects;*/
},
error: function(error) {
return error;
}
});
}
}
})
I have tried a few ways to make this work (using sources like the ionic forum, stackoverflow and Google in general), but I am new to angular and not sure how to go about doing this.
The only thing that works is by putting the following code in the controller (but then I cannot use ng-repeat):
$scope.searchnow = function () {
var queryvalue = $scope.user.queryvalue;
userquery.startsWith("username", queryvalue); // Search username
userquery.limit(20);
userquery.find({
success: function(people) {
for (var i = 0; i < people.length; i++) {
var object = people[i];
console.log("ID: " + object.id + ', username: ' + object.get('username'));
}
}, error: function(error) {
console.log("error");
}
});
};
Has anyone implemented such a service for parse.com?
I have looked around and tried implementations from various people, but nothing seems to work in a way that returns a service like response from which ng-repeat comands can be done.
I believe this might help.
Services:
app.factory('Presentation', function($q) {
var Presentation = Parse.Object.extend(Parse.User, {
// Instance methods
}, {
// Class methods
listByUser : function() {
var defer = $q.defer();
var query = new Parse.Query(this);
query.startsWith("username", searchVal); // Search username
query.limit(20);
query.find({
success : function(aPresentations) {
defer.resolve(aPresentations);
},
error : function(aError) {
defer.reject(aError);
}
});
return defer.promise;
}
});
// Properties
Presentation.prototype.__defineGetter__("location", function() {
return this.get("location");
});
Presentation.prototype.__defineGetter__("pic", function() {
var pic = this.get("pic");
if (pic ==null){
pic = 'img/default.png';
return pic;
}
return pic.url();
});
return Presentation; });
Controller:
app.controller('userController', function( Presentation){
user = this;
Presentation.listByUser().then(function(aPresentations) {
user.list = aPresentations;
}, function(aError) {
// Something went wrong, handle the error
});
});
html:
<div class="row">
<div class="col col-75">
<label class="item item-input">
<i class="icon ion-search placeholder-icon"></i>
<input type="text" placeholder="Search" ng-model="search.queryvalue">
</label>
</div>
<div class="col">
<button class="button button-calm" ng- click="searchnow()">Search</button>
</div>
</div>
<ion-list>
<ion-item class="item-avatar" type="item-text-wrap" ng-repeat="user in users">
<img ng-src="{{user.pic}}">
<h2>{{user.id}}</h2>
<p>{{user.location}}</p>
</ion-item>
</ion-list>
For further reading you can check out 5 Tips for using parse with angularjs by slidebean.

Resources