Exposing a factory JS variable globally within an AngularJS environment

I am trying to access a variable created within a factory in another function in my AngularJS controllers. How can I achieve this and make the new calculated value available?

The variable I want to use is result.data.bkor_payamount = result.data.bkor_payamount.toFixed(2); from the factory, and I need it for myItem['unitPrice'] = result.data.bkor_payamount; in the ListController onPay function.

I have attempted creating a global variable, but it doesn't seem to work as expected. The original value gathered from the JSON URL is still being called instead of my calculation.

// Ionic Starter App

        // angular.module is a global place for creating, registering and retrieving Angular modules
        // 'starter' is the name of this angular module example (also set in a <body> attribute in index.html)
        // the 2nd parameter is an array of 'requires'
        angular.module('starter', ['ionic','ngCordova'])

        .run(function($ionicPlatform) {
          $ionicPlatform.ready(function() {

            if(window.cordova && window.cordova.plugins.Keyboard) {
              // Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
              // for form inputs)
              cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);

              // Don't remove this line unless you know what you are doing. It stops the viewport
              // from snapping when text inputs are focused. Ionic handles this internally for
              // a much nicer keyboard experience.
              cordova.plugins.Keyboard.disableScroll(true);
            }
            if(window.StatusBar) {
              StatusBar.styleDefault();
            }
          });
        })

        .config(function($stateProvider, $urlRouterProvider) {

          $stateProvider
            .state('tabs', {
              url: '/tab',
              cache: false,
              abstract: true,
              templateUrl: 'templates/tabs.html'
            })
            .state('tabs.home', {
              url: '/home',
              cache: false,
              views: {
                'home-tab' : {
                 templateUrl: 'templates/home.html'
                }
              }
            })
            .state('tabs.list', {
              url: '/list',
              cache: false,
              views: {
                'list-tab' : {
                 templateUrl: 'templates/list.html',
                 controller: 'ListController'
                }
              }
            })

              // if none of the above states are matched, use this as the fallback
              $urlRouterProvider.otherwise('/tab/home');

        })

        .factory('httpInterceptor', function($q, $rootScope, $window) {
            var httpInterceptor = {
                response: function(response) {
                    var deferred = $q.defer();
                    var results = response.data;
                    var urlStart = 'http://example.com/';
                    if (response.config.url.startsWith(urlStart)) {
                        angular.forEach(results, function(result, key) { 
                            result.data.estCardFee = 2.00;
                            result.data.bkor_bookingfee = result.data.estCardFee;
                            result.data.bkor_payamount = +result.data.bkor_subtotal + +result.data.bkor_handling + -result.data.bkor_discount + +result.data.bkor_adjustment + +result.data.bkor_bookingfee;
                            result.data.bkor_payamount = result.data.bkor_payamount.toFixed(2);
                            result.data.bkor_paypalamount = result.data.bkor_payamount;
                        });
                    }
                    deferred.resolve(response);
                    return deferred.promise;
                }
            };
            return httpInterceptor;
        })
        .config(function($httpProvider) { 
            $httpProvider.interceptors.push('httpInterceptor'); 
        })

        .controller('ListController', ['$scope', '$http', '$state','$stateParams', '$window', '$location', '$ionicPopup', function($scope, $http, $state, $stateParams, $cordovaBluetoothSerial, $window, $location, $ionicPopup) {

                  $scope.query = '';

                  $scope.getOrders= function(query){

                         $http.get('http://example.com/' + query).success(function(data) {
                          $scope.orders = data;
                          console.log($scope.query);
                          console.log(data);
                          console.log($scope.orders);

                         })
                  }

                //$scope.orders = [];

                 function onPay(order) {
                 var itemsArr = [];
                 var invoice = {};
                 var myItems = {};
                 var myItem = {};

                 myItem['unitPrice'] = result.data.bkor_paypalamount;
                 myItem['taxRate'] = '0.0';
                 myItem['taxName'] = 'Tax';
                 itemsArr.push(myItem);
                 myItems['item'] = itemsArr;

                 invoice['itemList'] = myItems;
                 invoice['paymentTerms'] = 'DueOnReceipt';
                 invoice['currencyCode'] = 'GBP';
                 invoice['discountPercent'] = '0';

                 var returnUrl = "http://example.com/";
                 var retUrl = encodeURIComponent(returnUrl + "?{result}?Type={Type}&InvoiceId={InvoiceId}&Tip={Tip}&Email={Email}&TxId={TxId}");
                 var pphereUrl = "paypalhere://takePayment/v2?returnUrl=" + retUrl;
                 pphereUrl = pphereUrl + "&accepted=cash,card,paypal";
                 pphereUrl = pphereUrl + "&step=choosePayment";
                 pphereUrl = pphereUrl + '&invoice=' + escape(JSON.stringify(invoice));
                 console.log(pphereUrl);

                 return pphereUrl;

                 }


                $scope.pay = function (order) {
                $scope.showButton = true;
                var url = onPay(order);
                window.open(url, "_system");
                }

        }]);

Answer №1

Currently occupied, but I suggest reinserting the results into the data field of your resolve object within your httpInterceptor factory. Additionally, I have updated the references to result in your forEach() function to results[key] to ensure it properly modifies the original array (assuming it is an array).

       .factory('httpInterceptor', function($q, $rootScope, $window) {
        var httpInterceptor = {
            response: function(response) {
                var deferred = $q.defer();
                var results = response.data;
                var urlStart = 'http://example.com/';
                if (response.config.url.startsWith(urlStart)) {
                    angular.forEach(results, function(result, key) { 
                        results[key].data.estCardFee = 2.00;
                        results[key].data.bkor_bookingfee = results[key].data.estCardFee;
                        results[key].data.bkor_payamount = results[key].data.bkor_subtotal + results[key].data.bkor_handling - results[key].data.bkor_discount + results[key].data.bkor_adjustment + results[key].data.bkor_bookingfee;
                        results[key].data.bkor_payamount = parseFloat(results[key].data.bkor_payamount).toFixed(2);
                        results[key].data.bkor_paypalamount = results[key].data.bkor_payamount;
                    });
                }
                response.data = results;  //restore modified items back to the response
                deferred.resolve(response);
                return deferred.promise;
            }
        };
        return httpInterceptor;
    })

Answer №2

Angular services are designed as singletons, meaning you can store results within a property of the service instance and inject it into any controllers that need access to the data

If you want these results to persist through a page refresh, utilizing local storage is necessary

It's worth mentioning that although not recommended, another option would be to store the data in the global window object

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What sets my project apart from the rest that makes TypeScript definition files unnecessary?

Utilizing .js libraries in my .ts project works seamlessly, with no issues arising. I have not utilized any *.d.ts files in my project at all. Could someone please explain how this functionality is achievable? ...

Tips for validating forms using jQuery

Upon form submission, an alert is displayed before redirecting to a new page. I have implemented a function that triggers on button click. The alert will appear first, followed by the form submission. I would appreciate ideas on how to validate the form. ...

Filtering an array of JSONs in Vue.js using a separate array of JSONs

In my code, there are two arrays of JSONs: one named products and another called deletedProducts. The task is to filter out the products that are not present in the deletedProducts array. For instance: products = [ { id: 1, name: 'Box&apos ...

Disabling the submit button on an MC form - step by step guide

In order to create a multiple-choice question with radio buttons, each question must have only one answer choice. Each question should provide three options for the user to select from. It is necessary to validate whether the user has answered every questi ...

Updating the TextField in React Material UI based on the Slider value without affecting the Slider

Is there a way to update the value of a TextField based on the slider, while still allowing manual input in the TextField? I want the TextField to reflect changes from the slider but not vice versa. I attempted making the TextField a controlled component ...

Selecting Texture Coordinates

My goal is to pinpoint where a user has clicked on a texture of an object to trigger a response by redrawing the texture. I've been able to achieve this by rendering my objects with a color-coded texture onto a separate render target and using gl.rea ...

Error: The function clickHandler has been referenced before it was declared or it has already been declared

Since I started using JSLint, I have encountered the common issues of "used before defined" and "is already defined." While I found solutions for some problems, I am currently stuck. Here is a snippet of my code: var foo; foo = addEventListener("click" ...

Refresh the HTML table following each AJAX request

Each time my AJAX requests are made, new rows keep getting added to my HTML table. I need the table to be updated with fresh data on each call, without appending. This is my current code: var data = $('#data_input').val(); var tableRef = docume ...

Looking for a specific Greek symbol within a JavaScript string

I'm currently attempting to find a solution for replacing a Greek letter within a string with another character. For instance: value = "Hello μ!"; value.replace("μ", "You"); alert(value); //Expected result: Alerted value should be "Hello You!" Re ...

Submit button in React form not activating the onSubmit method

Having an issue with a login form code where the submit handler is not being triggered when pressing the Submit button. Any idea what could be causing this? The loginHandler function does not seem to trigger, but the handleInputChange function works fine. ...

The error message "TextEncoder is not defined with mongodb nodes" is indicating that there is

Encountering an issue while running jest test cases: Getting the error message - ReferenceError: TextEncoder is not defined. Current Node version being used is 14.18.0. Mongodb NPM package version is 4.1.3. Typescript version installed is 4.4.3. Here ...

Error message: When attempting to create dynamic inputs in React, an error occurs stating that instance.render is not

I encountered an issue while attempting to create dynamic inputs in React. The error message 'TypeError: instance.render is not a function' keeps popping up. import React, { Component } from 'react'; import Input from '../../Ui/Inp ...

Vue JS ensures that it has all the necessary data before proceeding with the

I've been grappling with a VueJS data rendering issue for a few weeks now. My approach involves making axios calls, some nested within others. The problem I'm facing is that the data renders before the calls have completed, resulting in an empty ...

What is the solution for halting code execution in a foreach loop with nested callbacks?

Currently, I am in the process of setting up a nodejs database where I need to retrieve user information if the user exists. The issue I'm facing is that when I return callback(null) or callback(userdata), it does not stop the code execution and resul ...

Can you explain the purpose of the _app.js and _document.js files in Next.js? What is the significance of using an underscore (_) in Next.js?

After using npx create-next-app to create a next.js app, I noticed that there are 2 JavaScript files named app and document in the pages directory with an initial underscore. What is the purpose of this naming convention? The files appear like this: ▼ p ...

Error encountered when trying to run gulp app:serve rails due to missing module 'require-dir'

After successfully installing npm, bower, and gulp, I encountered an issue when trying to run gulp app:serve. The error message is as follows: Please assist me in resolving this problem. The command I entered was: sachin@sachin:~/Desktop/workspace/myproj/a ...

What is the best way to pass props down to grandchildren components in React?

I'm trying to pass some props from a layout to its children. The issue is, it works fine when the child component is directly nested inside the layout, but it doesn't work when the child component is wrapped in another element like a div. Exampl ...

Error message: "Reactjs - TypeError: The property 'map' cannot be read as it is undefined in the table"

I have encountered an issue while using the material-ui table. I am able to map the items and display them successfully, but when trying to map the orders.items in the table, I get the following error: TypeError: Cannot read property 'map' of u ...

Utilizing Express Routes to specify React page components

Currently, as I delve into the world of learning Express.js, I find myself faced with a unique scenario involving 2 specific URLs: /security/1 /security/2 As per the requirements of these URLs, the expected response will vary. If the URL is "/securi ...

Displaying an array of objects in the MUI Datagrid interface

I have integrated Redux into my project to retrieve data from the API, and this is a snapshot of the data structure: https://i.stack.imgur.com/jMjUF.png My current challenge lies in finding an effective way to display the information stored within the &a ...