I am porting an ES5 Angular application to ES6 + Babel + Browserify and I am trying to create a specific class that is used for transforming data. Essentially the architecture looks like this:
API Response -> Transformation Layer -> Controller
And I wanted to create a transformation class that is generic and can be used for any scenario, then use inheritance or composition to implement specific examples of that transformation logic.
Here is my skTransform class
class skTransform {
constructor(transformRequest, transformResponse){
this.transformationRequestFn = transformRequest;
this.transformationResponseFn = transformResponse;
}
request(data){
var transformed = null;
if(data.constructor === Array){
transformed = [];
data.forEach((item) => {
transformed.push(this.processRequest(item));
});
}else{
transformed = this.processRequest(data);
}
return transformed;
}
processRequest(item){
if(this.transformationRequestFn.constructor == Array){
this.transformationRequestFn.forEach((transformFn) => {
item = transformFn(item);
});
}else {
item = this.transformationRequestFn(item);
}
return item;
}
response(data){
var transformed = null;
if(data.constructor === Array){
transformed = [];
data.forEach((item) => {
transformed.push(this.processResponse(item));
});
}else{
transformed = this.processResponse(data);
}
return transformed;
}
processResponse(item){
if(this.transformationResponseFn.constructor == Array){
this.transformationResponseFn.forEach((transformFn) => {
item = transformFn(item);
});
}else {
item = this.transformationResponseFn(item);
}
return item;
}
static Self(){
return skTransform;
}
}
skTransform.$inject = [];
export default skTransform;
Then I wanted to use composition (I think composition is better here regardless) to implement this transformation logic for a specific API:
class ExchangeTransformService {
constructor(skTransform){
this.transform = new skTransform(null, [this.ExchangeMailboxesResponse]);
}
response(data){
debugger;
data = this.transform.response(data);
return data;
}
ExchangeMailboxesResponse(data){
// THIS IS WHERE 'this' BECOMES UNDEFINED
this.applyUI(data.IndividualMailboxes);
this.applyUI(data.SharedMailboxes);
this.applyUI(data.PublicFolders);
return data;
}
applyUI(mailboxes){
// Do some work here
}
static CreateInstance(skTransform){
return new ExchangeTransformService(skTransform);
}
}
ExchangeTransformService.CreateInstance.$inject = ['skTransform'];
export default ExchangeTransformService;
If you look at the comment inside the ExchangeMailboxesResponse method you can see that at this point the code throws exceptions because this is undefined. I understand that this is based off the context of the calling method which in this case is inside the processResponse method, however, I have not dealt with ES6 very much so have not ran into this issue before.
I can fix this real quick by just treating ExchangeMailboxesResponse as a closure and place the applyUI method inside of that method so it creates a closure around the applyUI method and therefore has access to it when its called. I just feel like doing that starts to go against the design patterns that ES6 is supposed to be reinforcing.
Is there a more elegant solution to this issue other than using closures/vanilla JS to get this to work?
Aucun commentaire:
Enregistrer un commentaire