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());
}