Persistent Angular Factory Variables Showing Outdated Data - Instances Stuck with Old Values

One of the challenges I faced was setting up a resource factory to build objects for accessing our API. The base part of the URL needed to be determined using an environment variable, which would include 'account/id' path segments when the admin user engaged with a client account.

However, there was an issue with the sessionStorage item holding the 'engagedAsId' not being read for instances created after engaging an account. A full reload of the app was required to reflect this change. Below is the relevant factory code:

myapp.factory('ResourceSvcFactory',
    ['$rootScope', '$resource', 
    function ($rootScope, $resource) {

    function ResourceSvcFactory (endpoint) {
        // vvv problem is here vvv
        var accountId = sessionStorage.getItem('engagedAsId');
        var apiPath = (accountId != null) 
            ? '/api/account/' + accountId + endpoint 
            : '/api' + endpoint;

        var Resource = $resource(apiPath+':id/',{
            // default params
            id:''
        },{
            // custom actions 
            update: {method: 'PUT'}
        });

        return Resource;
    }

    return ResourceSvcFactory;
}]);

myapp.factory('AssetsResource', ['ResourceSvcFactory', function (ResourceSvcFactory) {

    var endpoint = '/assets/';
    var Resource = ResourceSvcFactory(endpoint);

    return Resource;
}]);

The implementation in my Controller looks like this:

myapp.controller('AssetGroupListCtrl', [ 'AssetgroupsResource', function (AssetgroupsResource) {

    var AssetGroups = AssetgroupsResource;

    // ... rest of controller
}]);

Everything works fine when I run it. However, changing the engaged status in the sessionStorage without a full reload does not update the instance in the controller. Is there a way to automatically refresh the instance?

Answer №1

After conducting extensive research, I have realized that the main issue with my approach is trying to utilize a 'singleton' as a 'class.' As stated in the documentation:

Note: All services in Angular are singletons. This means that the injector only uses each recipe once to create the object and then caches the reference for future use. http://docs.angularjs.org/guide/providers

To work around this limitation, I decided to create the $resource within a method of a returned object. Here's an example of how I implemented it: MyApp.factory('AssetgroupsResource', ['$rootScope', '$resource', function ($rootScope, $resource) {

    return {
        init: function () {
            var accountId = sessionStorage.getItem('engagedAsId');
            var apiPath = (accountId != null) 
                ? '/api/account/' + accountId + endpoint 
                : '/api' + endpoint;
                // default params
                id:''
            },{
                // custom actions 
            });
            return Resource;
        }
    }
}]);

By structuring it this way, I was able to instantiate the object at the appropriate time within the controller:

MyApp.controller('AssetGroupListCtrl', ['Assetgroups', function (Assetgroups) {
    var Assetgroups = AssetgroupsResource.init();
    // now I can leverage angular's $resource interface
}]);

Hopefully, this solution proves helpful to others. (Or perhaps someone will enlighten me on a more concise three-line solution!)

Answer №2

When you need to trigger an update in Angular, simply use $scope.$apply();.

To learn more about this process, check out this helpful tutorial:

Answer №3

It appears that the $resource module is utilizing promises, which could potentially cause problems depending on how your factory is integrated into your controller.

Be cautious when using $scope.$apply() as it can lead to errors if not used correctly. A safer approach to ensure proper functioning of Angular is

$rootScope.$$phase || $rootScope.$apply();
.

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

Add an item to an array and then transform the array into a JSON format

I have a situation where I am creating an object and pushing it into an array. After that, I convert it into JSON format. When I display the dataCharts using an alert, it is returned in this form: [{"AllLinks":"Link9","LinkURL":"url1"},{"AllLinks":"Link6" ...

Once the timer has finished, I would like for a specific component to be displayed

I am trying to make my component CountDownSquare disappear once the timer has fully counted down. In my homePageData, I have the main text stored in a h3 element that should only appear once the countdown is complete. I attempted to use a ternary stateme ...

Is there a way to plot countries onto a ThreeJS Sphere?

Currently engaged in a project involving a 3D representation of Earth. Successfully created a 3D Sphere using ThreeJS ...

What are some strategies for optimizing speed and efficiency when utilizing jQuery hover?

While developing a web application, I have created a grid using multiple div elements that are X by Y in size, determined by user input. My goal is to change the background color of surrounding divs within a certain distance when hovering over one particul ...

Using jQuery to find duplicated records within two JSON object arrays

Here is the structure of my first Json Array: [ {"Invent":"4","Beze":"256","mail":"<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="96f7f4f5d6f7f4f5b8f5f9fb">[email protected]</a>"}, {"Invent":"4","Beze":"2 ...

Ways to include input values

In my form, there are 4 text boxes labeled as customer_phy_tot, customer_che_tot, and customer_bio_tot. I want to add up the values entered in these 3 boxes and display the sum in a 4th input box called customer_pcb_tot. customer_bio_obt.blur(function(){ ...

calls to res.send and res.render

I'm currently trying to determine if it's possible to use res.send(data) and res.render('reports') simultaneously in my code. To provide more details, when I navigate to '/reports', on the server side I am executing a REST ca ...

Having trouble retrieving the token from the request on the server side

In the example I found here, I attempted to set the token on the header from the front end using $localStorage. I have confirmed that the token is stored in $localStorage. $httpProvider.interceptors.push(['$q', '$location', '$loca ...

Contact form repair completed - Messages successfully delivered

I am facing an issue with the contact form on my HTML landing page. Currently, when you click the 'Submit' button, it redirects to a new PHP page displaying 'Success'. Is there a way to make it so that upon clicking 'Submit' a ...

Is it possible to activate or deactivate a button depending on a radio button selection using jQuery?

Below is the code I have written in an aspx file: <asp:Button ID="btn" runat="server" Text="Add As a Sub Organization" OnClick="lnkChild_Click" ValidationGroup="GroupA" class="btn-u" CausesValidation="true" /> <asp:GridView ID="grdDuplicateO ...

Tips for attaching to a library function (such as Golden Layout) and invoking extra functionalities

I am currently utilizing a library named Golden Layout that includes a function called destroy, which closes all application windows on window close or refresh. My requirement is to enhance the functionality of the destroy function by also removing all lo ...

The function was expecting an array for ordering, but instead received an object

I need help filtering my results based on their position. Whenever I try to use the orderBy function, it breaks the page because the result is not an array. How can I fix this issue? I'm currently stuck at this point. This is how I attempt to filter ...

Using Mongoose to Perform Lookup with an Array as a Foreign Key

In my database, I have a collection called questions which contains fields like _id, name, and more. Additionally, there is another collection named tests with fields such as _id, name, and an array of questions. My goal is to retrieve all the questions a ...

Ways to loop through an array of daytime values and exhibit just the records for the current week

ng-repeat="day in task.DailyWorks | limitTo : weekdays.length: weekStart" This iteration process enables me to showcase the daily work records in a structured format within the table columns. The feature allows for seamless navigation between different we ...

After submitting my form, the Bootstrap Modal does not hide as intended by my Ajax

I am facing an issue with my webpage that displays 6 Bootstrap Cards in 3 columns. Each card contains an image, name, description, and a footer button. When a user clicks on the button, a Bootstrap Modal opens with specific data fetched from a SQL row by I ...

What is the best way to simultaneously check two conditions in Vue.js?

In my current scenario, I am facing a challenge with checking both conditions simultaneously. If an attachment exists in the request but the attachment field does not exist in the form, it should display a message in the modal. Similarly, if body text exis ...

Struggling to dynamically append additional textboxes to a <div> element using JavaScript

After spending over 12 hours on this problem, I am completely stuck and frustrated. I have tried countless variations and sought out other solutions to no avail. It should be a simple task. My project involves using JQueryMobile 1.2 along with its dependen ...

Saving information on localStorage is not possible

Recently, I created a demo for a basic Login and Logout application that utilizes an access token. If a user attempts to access another page without logging in (meaning the access token is null), they are redirected back to the Login page. Initially, I use ...

The query attribute of the http_incomingmessage in Node.js is not empty, causing Express to have trouble parsing the query parameter

While utilizing node version 6.9.4 and express version 4, there seems to be an issue with the creation of the IncomingMessage object in _http_common.js. Specifically, on line number 60, the parser.incoming.query function is being set to a value (usually it ...

Tips for canceling an http request in angularjs when the requesting controller has exited its scope

Developed a custom angularjs application with ng-view for loading four different modules using route provider. Each module makes HTTP requests as shown below: var requestManager = { "locations": {}, "employees": {}, "items": {}, "templates ...