Reputation: 13517
I'm new to Angular, and my guess is I don't understand $resource and promises enough.
I'm trying to create a shared data scenario where I have a retrieval service that gets data fresh from a web api, and a shared service which my controllers can bind to for working with the data.
However, the data I'm expecting to display in the controller line vm.lines = sharedService.getLines(this.id);
never gets displayed even though I can see that the web api is delivering the data to the retrievalService.
Can anyone nudge me in the right direction here?
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'm trying to follow advice from John Papa at for how to do shared data across controllers.
UPDATE WITH FULL SOLUTION Here are the changes I had to make to get this to work:
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());
}
Upvotes: 0
Views: 83
Reputation: 1912
when you breakpoint this._lines = data
does debugger hit it? This kind of reminds me of the common issue where this
is undefined. You may need to do var self = this
outside of the callback function and then say self._lines = data
Upvotes: 1
Reputation: 1349
I think it's because you need to return $resource.query
from your service.
getLines(id: string): app.ILine[] {
if(!this._lines) {
var resource = this.dataService.getLines(id);
return resource.query((data: app.ILine[]) => {
this._lines = data
});
}
return this._lines;
}
Upvotes: 1