What might be causing the absence of the shared Angular service data?

I'm new to Angular, and it seems like my understanding of $resource and promises is lacking.

My goal is to set up a scenario where I can retrieve fresh data from a web API using a retrieval service and then have a shared service that controllers can use to work with that data.

However, when I try to display the data in the controller using

vm.lines = sharedService.getLines(this.id);
, the data doesn't show up even though I know the web API is sending the data to the retrievalService.

Can someone provide some guidance on how to resolve this issue?

Data Retrieval service:

module services {
    "use strict";

    export interface IRetrievalService {
            getLines(id: string): ng.resource.IResourceClass<IResource>;
        }

    interface IResource extends ng.resource.IResource<app.ILine> { }

    export class RetrievalService implements IRetrievalService {

        static $inject = ['$resource'];
        constructor(private $resource: ng.resource.IResourceService) {

        }

        getLines(id: string): angular.resource.IResourceClass<IResource> {
            return this.$resource("api/myUrl/?id=" + id);
        }
    }

    angular
        .module("services")
        .service("app.services.retrievalService", RetrievalService );
}

Shared Service

module services {
    "use strict";

    export interface ISharedService {
        _lines: app.ILine[];
        getLines(id: string): app.ILine[];
    }

    export class SharedService implements ISharedService {
        _lines: app.ILine[];

        static $inject = ["app.services.retrievalService"];
        constructor(private dataService: app.services.DataService) {

        }

        getLines(id: string): app.ILine[] {
            if (!this._lines) {
                var resource = this.dataService.getLines(id);
                resource.query((data: app.ILine[]) => {
                    this._lines = data
                });
            }

            return this._lines;
        }
    }

    angular
        .module("services")
        .service("app.services.sharedService", SharedService);
}

Controller/Component

module app {
    "use strict";

    interface ILinesScope {
        id: string;
        lines: app.ILine[];
    }

    class LinesComponentController implements ILinesScope {
        id: string;
        lines: app.ILine[];

        static $inject = ["app.services.sharedService"];
        constructor(private sharedService: services.SharedService) {
            var vm = this;

            vm.id = "5";
            vm.lines = sharedService.getLines(this.id);
        }
    }

    class LinesComponent implements ng.IComponentOptions {
        templateUrl = "app/Lines.html";
        controllerAs = "vmLines";
        controller = ["app.services.sharedService", LinesComponentController];
    }

    angular.module("app")
        .component("myLines", new LinesComponent());
}

html

<div>
    <table>
        <thead>
        <tr>
            <th>column 1</th>
            <th>column 2</th>
        </tr>
        </thead>
        <tbody>
        <tr ng-repeat="line in vmLines.lines">
            <td>{{line.col1}}</td>
            <td>{{line.col2}}</td>
        </tr>
        </tbody>
    </table>
</div>

I found inspiration from John Papa regarding shared data in Angular applications.

UPDATE WITH FULL SOLUTION Here are the changes I had to make to ensure everything works correctly:

Shared Service:

module services {
    "use strict";

    export interface ISharedService {
        //_lines: app.ILine[];
        _lines: ng.resource.IResourceArray<ng.Resource.IResource<ILine>>
        //getLines(id: string): app.ILine[];
        getLines(id: string): ng.resource.IResourceArray<ng.Resource.IResource<ILine>>

    }

    export class SharedService implements ISharedService {
        //_lines: app.ILine[];
        _lines: ng.resource.IResourceArray<ng.Resource.IResource<ILine>>

        static $inject = ["app.services.retrievalService"];
        constructor(private dataService: app.services.DataService) {

        }

        //getLines(id: string): app.ILine[] {
        getLines(id: string): ng.resource.IResourceArray<ng.Resource.IResource<ILine>> {
            var vm = this;
            if (!this._lines) {
                var resource = this.dataService.getLines(id);
                return resource.query();
                //resource.query((data: app.ILine[]) => {
                //    this._lines = data
                //});
            }

            return this._lines;
        }
    }

    angular
        .module("services")
        .service("app.services.sharedService", SharedService);
}

Controller/Component:

module app {
    "use strict";

    interface ILinesScope {
        id: string;
        //lines: app.ILine[];
        lines: ng.resource.IResourceArray<ng.Resource.IResource<ILine>>;
    }

    class LinesComponentController implements ILinesScope {
        id: string;
        //lines: app.ILine[];
        lines: ng.resource.IResourceArray<ng.Resource.IResource<ILine>>;

        static $inject = ["app.services.sharedService"];
        constructor(private sharedService: services.SharedService) {
            var vm = this;

            vm.id = "5";
            vm.lines = sharedService.getLines(this.id);
        }
    }

    class LinesComponent implements ng.IComponentOptions {
        templateUrl = "app/Lines.html";
        controllerAs = "vmLines";
        controller = ["app.services.sharedService", LinesComponentController];
    }

    angular.module("app")
        .component("myLines", new LinesComponent());
}

Answer №1

I believe the reason for this is that you should be returning $resource.query from your service.

fetchLines(id: string): app.ILine[] {
   if(!this._lines) {
      var resource = this.dataService.fetchLines(id);
      return resource.query((data: app.ILine[]) => {
         this._lines = data
      });
   }
   return this._lines;
}

Answer №2

Have you checked if the debugger hits when you set a breakpoint at this._lines = data? This situation is similar to the common problem where this is undefined. One solution could be to declare var self = this outside of the callback function and then assign self._lines = data.

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

Unable to access attributes of an object that has not been defined (referencing 'providers')

https://i.sstatic.net/9Ntvd.png When I try to import web3 version 1.2.11, I am using the following code in TypeScript: import Web3 from 'web3' const readonlyProvider = new Web3.providers.HttpProvider(providerURL) However, after compiling it, ...

Maintain modifications in AngularJS modal even after closure

I have an HTML file with some AngularJS code for a modal window. <div ng-controller="ModalDemoCtrl"> <script type="text/ng-template" id="myModalContent.html"> <div class="modal-header"> <h3>I'm a modal!</h3> ...

Choose the AuthGuard category in real-time

My application intends to employ two distinct authentication strategies - one for users accessing via a browser and another for the public API. A specific header will be set for browser users, allowing my app to determine the appropriate auth strategy base ...

Encountering a Problem: [$injector:modulerr] Inability to Create App Module in AngularJS + Karma + Jasmine Setup

We are currently working on a large project that involves multiple controllers, factories, configs, and more. Recently, I decided to integrate karma+ jasmine for writing unit test cases. However, I am encountering the error mentioned above. Despite trying ...

Issue with page layout arises due to a problem with AngularJS directive

I recently downloaded the Ace Admin template from As I tried to integrate it into my AngularJS project, I encountered a problem when using specific parts of the template in custom directives. To isolate and simplify the issue, I created a plunker at https ...

Why isn't my Angular directive able to access the parent controller's scope within its isolated scope?

I have meticulously followed the Angular documentation to implement a directive with an isolated scope that contains a few variables from the parent Controller's scope object. app.controller('MainCtrl', function($scope) { $scope.name = ...

Is it possible to retrieve 2 arguments within a function in a non-sequential manner?

Let's say there is a function with arguments A, B, C, D, and E. Function(A, B, C, D, E) However, not all arguments are needed all the time. For instance, only A and C are needed in some cases. Currently, I would have to call the function like this: Fu ...

Next.js React Server Components Problem - "ReactServerComponentsIssue"

Currently grappling with an issue while implementing React Server Components in my Next.js project. The specific error message I'm facing is as follows: Failed to compile ./src\app\components\projects\slider.js ReactServerComponent ...

The discovery of a commitment in the statement. The automation of unwrapping promises within Angular statements has been phased out

Struggling with errors while setting up a new AngularJS project. Here is the code for my app and controller; var app = angular.module('myApp', ['localytics.directives']) .config(['$parseProvider', function ($parseProvide ...

Typescript is throwing a Mongoose error stating that the Schema has not been registered for the model

I've dedicated a lot of time to researching online, but I can't seem to figure out what's missing in this case. Any help would be greatly appreciated! Permission.ts (This is the Permission model file. It has references with the Module model ...

Is it possible to incorporate variables when utilizing NG-CLASS for an active link in Angular?

I am trying to create a navigation using a loop in my code. However, I keep encountering an error which says that it won't evaluate as a string. The idea is to loop through the $scope.navigation and use it to generate the navigation dynamically instea ...

Having trouble displaying values from nested JSON in a datatable

Response from server : ["{\"CLIENT\":[{\"tranche\":\"1-4\",\"prix\":\"65.96\",\"currency\":\"E\"}],\"DISTRIBUTEUR\":[{\"tranche\":\"1-4\",\"prix\ ...

Angular generates an array that is not native to the system

When I directly set vm.files in my view using the following code: <input type="file" ng-model= vm.files[0]> <input type="file" ng-model= vm.files[1]> The contents of vm.files are displayed as shown in example A: https://i.stack.imgur.com/K3V ...

There are no matching overloads in React for this call

Below is an error message in the code. It seems to be related to the usage of <IHistorical[]> in useQuery, but unfortunately, I haven't found a solution for it yet. Overload 1 of 2, '(props: Props | Readonly<Props>): ReactApexChart& ...

Incorporating typings for bootstrap-table while compiling TypeScript in an ASP.NET Core application

In my ASP.NET Core 5 app, I have chosen to use TypeScript instead of JavaScript. As part of this decision, I am utilizing some JavaScript libraries in my project and need type definitions for them to compile smoothly. To facilitate this process, I have co ...

What is causing the failure of this polymorphic assignment within a typed observableArray in Knockout?

Consider a scenario where we have a class A and its subclass B. The goal is to assign an array of instances of class B to an array of instances of class A. While this works with normal arrays, the same operation fails when using ko.ObservableArray. import ...

I encountered a problem when trying to set up ngx-Spinner version 8.0.3

I need help implementing a spinner loader in my app. I have followed the instructions provided at [ https://www.npmjs.com/package/ngx-spinner ] and successfully installed it. However, when trying to import and add it to "imports", I encountered the follow ...

Error Detected: An unhandled error occurred, triggering a promise rejection: TypeError: The super expression must be either null or a function in Angular version 6

Upon deploying the application on AWS Elastic Beanstalk, an error has surfaced. While the build and deployment processes were successful, one module is giving a Super Expression error. The other modules are functioning correctly, and everything works fine ...

What is the best way to create a dynamic string based on a list's contents?

To create a personalized message, I am looking to generate a string based on user input and then loop through a list of first names. For instance: Given a list of first names: let firstnameList = ["Jan", "Mark","Doe"] And a message entered by the user: ...

Transferring a picture from a computer to a Fabric.JS Canvas

Seeking Fabric.JS Experts! I've conducted thorough research but I'm struggling to find a clear explanation on how to add an image to the fabric.JS canvas. User Journey: a) User uploads an image using an input file type button. b) Once they sel ...