0

I have JavaScript Closure methods I need to convert in to TypeScript. I am not able to do that. Please help me. How to write a function inside a function in TypeScript?

var postPonedMethod1 = function() {
  var postPonedMethod2 = function() {
    this.getClaimNotices();
    this.gridServices.get();
    //$scope.gridServicesReciepts.get();
    $scope.setDataLoading(false);
  };
  postPonedMethod2();
} 
Heretic Monkey
  • 11,687
  • 7
  • 53
  • 122
Azeem
  • 11
  • 1
  • 7
  • 3
    unsure how it is any different in typescript. What is not working when you "converted it" into typescript? – epascarello Sep 15 '22 at 21:18
  • 1
    Yes, @epascarello is right, typescript does not touch the logic of the code, it only adds types during the development, once you build your code, there's only javascript left – Vincent Rouilhac Sep 15 '22 at 21:20
  • I am not access the method which is written in component class body. this.getClaimNotices(); this.gridServices.get(); I am getting error of undefined. – Azeem Sep 15 '22 at 21:56

2 Answers2

1

Your problem is the use of this: postPonedMethod2 refers to this, but it isn't a function defined on a class or object. If you're using popular TypeScript options --noImplicitThis or --strict, TypeScript will complain, because it is possible that you will eventually call postPonedMethod2 in a way that does not provide the expected this instance. In fact, in JavaScript's "strict mode" ("use strict";) you might find that this is undefined where it wasn't before.

In strict mode, however, if the value of this is not set when entering an execution context, it remains as undefined, as shown in the following example:

function f2() {
  'use strict'; // see strict mode
  return this;
}

f2() === undefined; // true

If possible, I'd switch to defining your AngularJS component as a class, calling this.postPonedMethod1() and this.postPonedMethod2() for clarity.

In general in TypeScript, the solution is to type the "this" outside a class is to define an argument called this as your function's first parameter, which tells TypeScript what type to expect. To temporarily get through the problem, though, you can explicitly set this: any. This defeats the purpose of TypeScript here, because any provides no type checking at all, but it would allow you to solve the problem later in a different commit.

That fixes the typing, but you'll still need to ensure that the value of this is set correctly where you call postPonedMethod2. This would mean one of:

  • Using an arrow function () => { instead of function () { for postPonedMethod2. An arrow function explicitly does not redefine this.
  • Calling bind(this) where postPonedMethod2 is defined, or using call as in postPonedMethod2.call(this) where you call it.
  • Avoiding "use strict" with --noImplicitUseStrict, if you're otherwise trying to emit a module.
  • Saving the outer value of this to a place where it won't be redefined, as I show below.
var postPonedMethod1 = function() {
  var postPonedMethod2 = function() {
    this.getClaimNotices(); // error: 'this' implicitly has type 'any' because it does not have a type annotation.
    this.gridServices.get(); // error: 'this' implicitly has type 'any' because it does not have a type annotation.
    //$scope.gridServicesReciepts.get();
    $scope.setDataLoading(false);
  };
  postPonedMethod2();
}

var fixedPostPonedMethod1 = function(this: any) { // Do better than "any" if you can.
  var component = this;                           // Store the enclosing "this".
  var postPonedMethod2 = function() {
    component.getClaimNotices();
    component.gridServices.get();
    //$scope.gridServicesReciepts.get();
    $scope.setDataLoading(false);
  };
  postPonedMethod2();                             // You could also call "bind".
}

Jeff Bowman
  • 90,959
  • 16
  • 217
  • 251
  • thanks for the answer i am new to type script this was bothering me as i am converting some one else code from angular js to type script. – Azeem Sep 16 '22 at 14:27
-1

It works for me like below

var postPonedMethod1 = () => {
  var postPonedMethod2 = () => {
    this.getClaimNotices();
    this.gridServices.get();
    //$scope.gridServicesReciepts.get();
    $scope.setDataLoading(false);
  };
  postPonedMethod2();


}
Azeem
  • 11
  • 1
  • 7
  • 1
    This is the same code that throws errors when you click "Run code snippet" as is present in the question. This would be an okay comment (albeit the same as existing ones), but does not make a good answer. – Heretic Monkey Sep 15 '22 at 22:30
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Sep 20 '22 at 11:12