0

So I am trying to calculate the discount price applied on items/products, based off of two variables: the Retail Price and the Sales Price. I created a function inside my AngularJS Service, called calculateDiscount, and I would like to return the calculated value on my view. My issue is that my view doesn't get updated with the calculated discount percentage for each item

Below is my code

HTML Markup:

<div class="articleItem swiper-slide" ng-repeat=
    "item in items | orderBy:'-likes'">
        <div class="sales-discount">
            <i class="icon-tag"></i> Save {{calculateDiscount(item)}}%
        </div>
        <div class="article-title">
            <span class="badge badge-rect-white">Bestseller</span>
            <span class="badge badge-rect-black">On sale</span>
            <h2 style=
            "font-family: 'Lato', Arial, Tahoma, sans-serif; font-size: 26px; margin: 0; line-height: 1.2; text-shadow: 1px 1px 0 rgba(0, 0, 0, 0.8); font-weight:900;">
            <a href="javascript:;" style=
            "color:#fff;">{{item.productName}}</a>
            </h2>
            <div class="shop-data" style="margin-top:10px;">
                <!--<span class="shop-price" style="font-weight:900;
                                                            background-color: rgb(62, 123, 42);
                                                            padding: 5px;
                                                            border-radius: 3px;
                                                            color: #fff;">
                                   {{item.price}}
                                </span>-->
                 <span class="shop-price" style=
                "font-weight:900; background-color: rgb(62, 123, 42); padding: 5px; border-radius: 3px; color: #fff;">
                {{item.saleprice}}</span> <span class="data"><span style=
                "font-weight:900"><input id="box1" ng-model="item.likes"
                ng-value="item.likes" type="checkbox"> <label for="box1"
                style=
                "padding: 5px; background-color: #222; position: relative; top: 0; border-radius: 3px; margin-right:5px;">
                {{item.likes}}</label> <input id="box2" ng-model=
                "item.comments" ng-value="item.comment_count" type=
                "checkbox"> <label for="box2" style=
                "padding: 5px; background-color: #222; position: relative; top: 0; border-radius: 3px; margin-right:5px;">
                {{item.comment_count}}</label> <input id="box3" ng-model=
                "item.shares" ng-value="item.share_count" type="checkbox">
                <label for="box3" style=
                "padding: 5px; background-color: #222; position: relative; top: 0; border-radius: 3px; margin-right:5px;">
                {{item.share_count}}</label></span></span>
            </div>
        </div><img alt="" class="itemImgStyler" ng-src="{{item.picture}}"
        style="width:100%;">
    </div>

Sample Data in data.json

    [

    {
        "_id": "5702bdbce518778bbc5add77",
        "index": 1,
        "guid": "694aafa9-b641-478a-a258-c2f0989f20dc",
        "isOnsale": true,
        "price": "$439.53",
        "saleprice": "$22.73",
        "picture": "https://s-media-cache-ak0.pinimg.com/564x/d7/24/f2/d724f20fb401e010d601842584b5419f.jpg",
        "review": 4,
        "size": "L",
        "brand": "GUESS",
        "productType": "BEAUTY",
        "category": "SWEATERS",
        "productName": "Guess Men's Grey Sweater Two-Tones",
        "company": "LUXURIA",
        "phone": "+1 (842) 527-3928",
        "address": "674 Autumn Avenue, Haena, Massachusetts, 471",
        "likes": 34,
        "comment_count": 6,
        "share_count":20,
        "description": "Eu exercitation labore sint laborum nisi consequat pariatur sunt. Ullamco sit dolor velit ea excepteur cupidatat amet id Lorem anim enim consectetur ipsum eu. Laboris Lorem id exercitation occaecat irure aliquip veniam in ut. Esse velit occaecat cillum fugiat mollit ullamco do non cupidatat nulla ea esse aliquip cupidatat. Consectetur duis laborum fugiat laboris. Adipisicing fugiat dolor velit incididunt. Fugiat nisi dolor consequat amet et sint et aliquip qui consectetur.",
        "comments": "Non et elit ullamco est officia in. Velit ut nisi sunt mollit. Adipisicing est amet ipsum anim. Sunt aliquip irure aliqua non labore ut nulla.\n\nIrure fugiat ullamco enim elit sunt exercitation nisi. Ex consequat amet velit do ea veniam Lorem anim ipsum dolore ipsum aliqua culpa irure. Mollit irure aliquip ad elit ut consectetur proident amet et veniam nulla deserunt cupidatat culpa. Do duis sit elit voluptate fugiat anim ad id irure. Deserunt amet veniam nisi non.",
        "registered": "Sunday, November 2, 2014 12:41 PM",
        "latitude": "-6.226487",
        "longitude": "-111.623657",
        "tags": [
            7,
            "consequat qui"
        ],
        "range": [
            0,
            1,
            2,
            3,
            4,
            5,
            6,
            7,
            8,
            9
        ],
        "friends": [
            3,
            {
                "id": 1,
                "name": "Webb Rodriguez"
            }
        ]
    },
    {
        "_id": "5702bdbc1406dffa4188cc24",
        "index": 2,
        "guid": "27c7292b-a6a7-4145-afba-def743043941",
        "isOnsale": true,
        "price": "$422.14",
        "saleprice": "$95.89",
        "picture": "https://s-media-cache-ak0.pinimg.com/564x/b0/4c/35/b04c353ddf167ad87b19fab56aa16ac3.jpg",
        "review": 3,
        "size": "XXL",
        "brand": "NIKE",
        "productType": "SNEAKERS",
        "category": "SHOES",
        "productName": "NIKE Men's Shoes Two-Tones",
        "company": "ZENTILITY",
        "phone": "+1 (827) 471-2811",
        "address": "650 Clifton Place, Keyport, Pennsylvania, 9913",
        "likes": 458,
        "comment_count": 149,
        "share_count":82,
        "description": "Cillum consectetur ut cupidatat officia ex elit aliqua. Quis nisi officia deserunt sit cillum commodo consectetur pariatur eu voluptate mollit qui magna. Culpa sunt qui nulla sit esse fugiat fugiat deserunt culpa.",
        "comments": "Mollit commodo dolore sit nulla. Ea excepteur cillum in ullamco. Laborum ea laboris voluptate anim laboris elit consectetur elit cillum.\n\nLabore esse laboris occaecat laboris. Velit exercitation in qui exercitation aliqua in qui. Consectetur reprehenderit culpa culpa exercitation commodo cupidatat consequat laborum reprehenderit non aliqua voluptate labore id. Deserunt dolor voluptate aliquip aliqua elit nulla id veniam laborum veniam aute magna minim. Ut non eiusmod qui cupidatat elit. Pariatur laboris duis ea qui in minim sit. Ut nostrud ex deserunt proident.",
        "registered": "Sunday, June 22, 2014 12:32 AM",
        "latitude": "-52.134773",
        "longitude": "77.284837",
        "tags": [
            7,
            "consequat qui"
        ],
        "range": [
            0,
            1,
            2,
            3,
            4,
            5,
            6,
            7,
            8,
            9
        ],
        "friends": [
            3,
            {
                "id": 1,
                "name": "Webb Rodriguez"
            }
        ]
    }
]

DataService

    (function (ng) {
    'use strict';

    angular.module('data.services', [ ])
        .factory('dataService', ['$http', function($http) {
            console.log('dataService');

            var urlBase = "main-services/data.json";
            var calculateDiscount;
            var dataItems = {};

            dataItems.getAllItems = function () {
                return $http.get(urlBase,{
                    cache:true
                });

            };

            dataItems.addNewItem = function (item) {
                return $http.post(urlBase+'/addNewItem', item);
            };
            calculateDiscount = function(item){
                return ((item.saleprice/item.price)*100);
            }

            return dataItems;


        }]);


}(angular));

3 Answers 3

1

I think, you get items in some controller's method something like this:

dataService.getAllItems()
    .then(function(response){$scope.items = response.data;})

If it's so, you could change your getAllItems method like this:

dataItems.getAllItems = function () {
   return $http.get(urlBase,{
                cache:true
            })
         .then(function(response){
               var items = response.data;
               items.forEach(function(item){
                   item.discount = calculateDiscount(item);
                })
               return items;
          });
    };

And, then, in your html, replace <i class="icon-tag"></i> Save {{calculateDiscount(item)}}% with <i class="icon-tag"></i> Save {{item.discount}}%. I didn't check this code for work, there may be some syntax errors, but it reflects conception

Sign up to request clarification or add additional context in comments.

7 Comments

Thanks for your answer. I guess my question now is where do I put the calculateDiscount function? Do I keep it inside of my Service? Could you please provide a full code of the Service? I will really appreciate it. Thanks.
Just leave calculateDiscount function as it is. Just replace your dataItems.getAllItems inside your service with my implementation and it must be working (as I said I didn't check it's syntax on some IDE). And don't forget to change template.
Here is the error I got from your implementation: TypeError: dataService.getAllItems(...).success is not a function
Oh, you are using success function in your controller! The $http legacy promise methods success and error have been deprecated. Use the standard then method instead - this is from angularjs documentation. Could you replace 'success' method with 'then' method inside your controller like I've wrote dataService.getAllItems() .then(function(response){$scope.items = response.data;})?
Here is the error now TypeError: dataService.getAllItems(...).then(...).error is not a function.
|
0

Try adding the calculateDiscount function to the dataItems object like the other functions so it will be returned.

dataItems.calculateDiscount = function(item){
    return ((item.saleprice/item.price)*100);
}

Comments

0

Natalia Kamaeva helped me figure it out in the chat room.

One mistake I made, and maybe it is the one that cost me an entire day, just dealing with debugging, is that in my Data.json file contained the $ sign for saleprice and price attributes of my item's object. So when I tried to return (item.saleprice/item.price)*100, I always got the value of NAN.

Once Natalia helped me figure it out in the chatroom, multiple implementations came to my mind. And I would like to share two of them:

1. The easy solution (Not always recommended, but works in certain cases)

<div class="articleItem  swiper-slide" ng-repeat="item in items | orderBy:'-likes'">
     <div class="sales-discount">
          <i class="icon-tag"></i>Save {{(item.saleprice/item.price)*100}}%
     </div>
</div>

This solution works if the calculated discount is a fixed function that will not be changed in the near future. But from a production/business standpoint, it makes more sense to store that variable somewhere, and be able to manipulate it.

And that brings me to the second solution

2. The Best Solution in my opinion (Thanks for Natalia :))

Is to bake the calculateDiscount function within the DataService. Below is the full implementation. I also cleaned up the code a little to only focus on the important aspect.

HTML MARKUP

<div class="articleItem  swiper-slide" ng-repeat="item in items | orderBy:'-likes'">
     <div class="sales-discount">
          <i class="icon-tag"></i>Save {{item.discount}}%</div>
</div>

SAMPLE DATA in data.json

[

{
    "_id": "5702bdbce518778bbc5add77",
    "index": 1,
    "guid": "694aafa9-b641-478a-a258-c2f0989f20dc",
    "isOnsale": true,
    "price": "439.53",
    "saleprice": "22.73",
    "picture": "https://s-media-cache-ak0.pinimg.com/564x/d7/24/f2/d724f20fb401e010d601842584b5419f.jpg",
    "review": 4,
    "size": "L",
    "brand": "GUESS",
    "productType": "BEAUTY",
    "category": "SWEATERS",
    "productName": "Guess Men's Grey Sweater Two-Tones",
    "company": "LUXURIA",
    "phone": "+1 (842) 527-3928",
    "address": "674 Autumn Avenue, Haena, Massachusetts, 471",
    "likes": 34,
    "comment_count": 6,
    "share_count":20,
    "description": "Eu exercitation labore sint laborum nisi consequat pariatur sunt. Ullamco sit dolor velit ea excepteur cupidatat amet id Lorem anim enim consectetur ipsum eu. Laboris Lorem id exercitation occaecat irure aliquip veniam in ut. Esse velit occaecat cillum fugiat mollit ullamco do non cupidatat nulla ea esse aliquip cupidatat. Consectetur duis laborum fugiat laboris. Adipisicing fugiat dolor velit incididunt. Fugiat nisi dolor consequat amet et sint et aliquip qui consectetur.",
    "comments": "Non et elit ullamco est officia in. Velit ut nisi sunt mollit. Adipisicing est amet ipsum anim. Sunt aliquip irure aliqua non labore ut nulla.\n\nIrure fugiat ullamco enim elit sunt exercitation nisi. Ex consequat amet velit do ea veniam Lorem anim ipsum dolore ipsum aliqua culpa irure. Mollit irure aliquip ad elit ut consectetur proident amet et veniam nulla deserunt cupidatat culpa. Do duis sit elit voluptate fugiat anim ad id irure. Deserunt amet veniam nisi non.",
    "registered": "Sunday, November 2, 2014 12:41 PM"

}
]

Notice here that there is no attribute for discount. This is going to be injected in our service because It is a calculated value.

Data Service

(function (ng) {
    'use strict';
angular.module('data.services', ['pinStyle'])
    .factory('dataService', ['$http', function ($http) {
        console.log('dataService');

        var urlBase = "main-services/data.json";
        var calculateDiscount;
        var dataItems = {};

        dataItems.getAllItems = function () {
            return $http.get(urlBase, {
                cache: true
            })
                .then(function (response) {
                    var items = response.data;
                    items.forEach(function (item) {
                        item.discount = calculateDiscount(item);
                    })
                
                return items;
                
                });
        };

        return dataItems;

    }]);

} (angular));

Controller Invocation

(function (ng) {
'use strict';

angular.module('feed.controllers', ['pinStyle', 'data.services'])
    .controller('feedController', ['$scope', 'dataService', function ($scope,dataService) {
        console.log('feedController');


        var items;
        var status;
        getItems();

        function getItems() {
            dataService.getAllItems()
                .then(function (itm) {
                    $scope.items = itm;
                    console.log($scope.items);
                });
        };
    }]);
}(angular));

The result of my console.log($scope.items); enter image description here

Notice how the discount variable is returned within the item itself

This is exactly what I wanted.to achieve.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.