I have a unique situation and I find myself quite stuck. I have a standard typescript class (.ts) extension, that needs to use methods from an angular2 service. So far I can't see a way to achieve this.
I'm going to try an explain this as simply as I possibly can, as my code base is currently quite complex.
The service in question is operation.service.ts:
import { Injectable } from '@angular/core';
import { Http, Response, Headers } from '@angular/http';
import { Operation } from './operation';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
@Injectable()
export class OperationService {
private operationCatalogue: Operation[] = [];
private url = './src/app/operation-catalogue/operations.json';
constructor(private http:Http) {
this.init();
}
init(){
this.fetchOperations().subscribe(res => {
var i;
for(i in res["operations"]){
this.operationCatalogue[i] = new Operation(res["operations"][i]["name"],
res["operations"][i]["description"],
res["operations"][i]["iconName"],
res["operations"][i]["inputs"],
res["operations"][i]["outputs"]
);
}
});
}
getOperations(){
return this.operationCatalogue;
}
fetchOperations(): Observable<Operation[]>{
return this.http.get(this.url).map(res => res.json());
}
/*
Get a single operation from the operation catalogue.
*/
getOperation(name: String): Operation {
var theOne;
for (var i = 0; i < this.operationCatalogue.length; i++){
if (this.operationCatalogue[i].name === name){
theOne = this.operationCatalogue[i];
}
}
return theOne;
}
}
You'll see from this code that the service builds an of these Operation objects from data found in a locally sourced .json file. In production, my application will get the data from a server rather than a local file.
The important method to note is getOperation() which takes a string and returns an Operation object from the array.
This service is a key part of my application, and is used to populate a HTML list in another component.
Now, I have another class, called WSJSerializer. Put simply, and just to give you some context, this class takes a JSON string which represents an array of Operation objects that were found on disk and turns them into Operation objects. In order to do this, WSJSerializer needs to use the getOperation() method of OperationService.
WSJSerializer.ts:
export class WSJDeserializer {
private jsonString : string;
private parsedString : Object;
constructor(string : String){
this.jsonString = <string> string;
this.parsedString = JSON.parse(this.jsonString);
}
public deserialize() {
var rootOp = this.parsedString["operation"];
var childOps = rootOp["operations"];
var numOps = childOps.length;
for (var i = 0; i < numOps; i++){
var childOp = childOps[i]["operation"];
this.deserializeObject(childOp);
}
}
private deserializeObject(operation : Object){
//NEED TO USE THE getOperation() METHOD HERE!!!!
}
}
This is the crux of my problem. I'm unable to interface with OperationService from WSJSerializer, I'm guessing it's some sort of angular restriction. I tried to import OperationService into WSJSerializer and then call the getOperation() method, but I got the following error:
WSJDeserializer.ts (25,26): Property 'getOperations' does not exist on type 'typeof OperationService'.)
How can I call the getOperation() method of OperationService from within WSJSerializer? If it's not directly possible, can I write some sort of interface (not an OO-concept interface) or helper class to solve the problem? Is there some other workaround?
Other information:
WSJSerializeris used in the root angular component of my application butOperationServiceis not.OperationServiceis used in a child component of the root component, of which the root component has direct access to via aViewChild().WSJSerializeris not a service because it needs to directly modify other angular components by calling their methods.
Root component where WSJSerializer is used:
import { WSJDeserializer } from './serialization/WSJDeserializer';
//services...
import { SerializationService } from './serialization/serialization.service';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
providers: [SerializationService]
})
export class AppComponent implements OnInit {
@ViewChild(PixiComponent) private pixiComponent : PixiComponent;
@ViewChild(LogComponent) private logComponent : LogComponent;
@ViewChild(EditGlobalNamesDialogBoxComponent) private globalNamesEditDialog : EditGlobalNamesDialogBoxComponent;
@ViewChild(GlobalNamesComponent) private globalNamesComponent : GlobalNamesComponent;
private globalNamesController : GlobalNamesController;
ngOnInit() {
this.globalNamesController = new GlobalNamesController(this.globalNamesEditDialog, this.globalNamesComponent, this.pixiComponent);
}
public leftMousedown(){
this.pixiComponent.clickFromOutside();
}
public rightMousedown($event){
$event.preventDefault();
this.pixiComponent.clickFromOutside();
}
//TODO: Escape key functionality
notifyEscapePressed(){
}
/*------------------------------------------------------------------------*/
// Following method for log functionality
public logData($event){
this.logComponent.logText($event);
}
/*------------------------------------------------------------------------*/
/*------------------------------------------------------------------------*/
// Following methods for global names functionality
// handled by this.globalNamesController
public globalNameEditRequest(data : EditGlobalNameRequestData){
this.globalNamesController.displayEditGlobalNamesDialogBox(data);
}
public setNewGlobalName(data : EditGlobalNameRequestData) {
this.globalNamesController.setNewGlobalName(data);
}
/*------------------------------------------------------------------------*/
/*------------------------------------------------------------------------*/
// Deserialization...
public deserialize($event){
var workspaceString : String = $event;
var deserializer : WSJDeserializer = new WSJDeserializer(workspaceString)
this.pixiComponent.resetCanvas();
deserializer.deserialize();
}
/*------------------------------------------------------------------------*/
}
OperationServiceas a dependency in yourWSJSerializerconstructor?OperationServiceintoWSJSerializerlike this:constructor(@Inject(OperationService) private operationService), but when I try to instantiateWSJSerializer, it gives me an error because it expects anOperationServiceobject to be passed in, even though it's being injected...WSJSerializeris not a service is because it needs to directly modify other angular components - which is not what services should be used for. I will edit my question to add this information.