LebroNan
LebroNan

Reputation: 159

Calling a function inside same class not working, typescript

I am new to typescript and I am having a problem with calling a function inside the same class: I have a function like this:

createPost(url: String, data: any) {
    $.ajax({
      url: url + "/" + GLOBAL.REGISTER_URL,
      type: "POST",
      data: data.serialize(),
      success: function() {
        console.log("success");
      },
      error: function(request, status, error) {
        console.log(request.responseText);
        console.log(status);
        console.log(error);
      }
    });
  }

And I am trying to call it here:

.on('success.form.bv', function(e) {
        $('#success_message').slideDown("slow"); // Do something ...
        $('#contact_form').data('bootstrapValidator').resetForm();

        // Prevent form submission
        e.preventDefault();

        // Get the form instance
        var $form = $(e.target);

        // Get the BootstrapValidator instance
        var bv = $form.data('bootstrapValidator');

        // XXX reassigning port for testing purposes only
        var result = "https://" + window.location.hostname + ":" + GLOBAL.PORT + "/" + GLOBAL.VERSION + "/rest" + GLOBAL.REGISTER_URL;

        this.createPost(result, $form);
      });

But this is not working, every time when I click the button, I got a error in the browser:

ERROR TypeError: this.createPost is not a function Stack trace: ../../../../../src/app/register/register.component.ts/RegisterComponent.prototype.ngOnInit/<@http://localhost:4200/main.bundle.js:839:13 dispatch@http://localhost:4200/assets/js-lib/jquery-3.1.1.min.js:3:10263 add/q.handle@http://localhost:4200/assets/js-lib/jquery-3.1.1.min.js:3:8325 trigger@http://localhost:4200/assets/js-lib/jquery-3.1.1.min.js:4:5806 trigger/<@http://localhost:4200/assets/js-lib/jquery-3.1.1.min.js:4:6310 each@http://localhost:4200/assets/js-lib/jquery-3.1.1.min.js:2:2813 each@http://localhost:4200/assets/js-lib/jquery-3.1.1.min.js:2:1001 trigger@http://localhost:4200/assets/js-lib/jquery-3.1.1.min.js:4:6289 _submit@http://localhost:4200/assets/js-lib/bootstrapValidator.js:549:13 validate@http://localhost:4200/assets/js-lib/bootstrapValidator.js:857:13 _init/<@http://localhost:4200/assets/js-lib/bootstrapValidator.js:109:21 dispatch@http://localhost:4200/assets/js-lib/jquery-3.1.1.min.js:3:10263 add/q.handle@http://localhost:4200/assets/js-lib/jquery-3.1.1.min.js:3:8325 ../../../../zone.js/dist/zone.js/http://localhost:4200/polyfills.bundle.js:2839:17 onInvokeTask@http://localhost:4200/vendor.bundle.js:49785:24 ../../../../zone.js/dist/zone.js/http://localhost:4200/polyfills.bundle.js:2838:17 ../../../../zone.js/dist/zone.js/http://localhost:4200/polyfills.bundle.js:2606:28 ../../../../zone.js/dist/zone.js/http://localhost:4200/polyfills.bundle.js:2913:24 invokeTask@http://localhost:4200/polyfills.bundle.js:3785:9 globalZoneAwareCallback@http://localhost:4200/polyfills.bundle.js:3803:17

This should be a simple function call, and I don't know what is going on, can anyone help me with this problem?

Upvotes: 0

Views: 2778

Answers (3)

joh04667
joh04667

Reputation: 7437

You're running into the problem because of closures. Normally Typescript and Angular work to make this a rare issue, but....you're using jQuery?

To fix:

change

createPost(url: String, data: any) {...}

to

createPost = (url: String, data: any) => {...}

The fat arrow or lambda function creates a lexical this which doesn't change scope.

...On a side note, why use jQuery with Angular 2+? Angular already does so much to capture and expose the DOM API, it seems like shooting yourself in the foot and purposefully overcomplicating things by subverting that with jQuery. Angular does enough to make jQuery completely unnecessary.

Upvotes: 0

federico scamuzzi
federico scamuzzi

Reputation: 3778

I think your problem is for the scope.. what i can suggest to you is to try something like:

.on('success.form.bv',(e) => { //<-- use arrow func
        $('#success_message').slideDown("slow"); // Do something ...
        $('#contact_form').data('bootstrapValidator').resetForm();

        // Prevent form submission
        e.preventDefault();

        // Get the form instance
        var $form = $(e.target);

        // Get the BootstrapValidator instance
        var bv = $form.data('bootstrapValidator');

        // XXX reassigning port for testing purposes only
        var result = "https://" + window.location.hostname + ":" + GLOBAL.PORT + "/" + GLOBAL.VERSION + "/rest" + GLOBAL.REGISTER_URL;

        this.createPost(result, $form);
      });

OR WRAP your this like:

var _that = this;
.on('success.form.bv', function(e) {
        $('#success_message').slideDown("slow"); // Do something ...
        $('#contact_form').data('bootstrapValidator').resetForm();

        // Prevent form submission
        e.preventDefault();

        // Get the form instance
        var $form = $(e.target);

        // Get the BootstrapValidator instance
        var bv = $form.data('bootstrapValidator');

        // XXX reassigning port for testing purposes only
        var result = "https://" + window.location.hostname + ":" + GLOBAL.PORT + "/" + GLOBAL.VERSION + "/rest" + GLOBAL.REGISTER_URL;

        _that.createPost(result, $form);
      });

Upvotes: 1

Reactgular
Reactgular

Reputation: 54821

Do not use function {} with TypeScript. Instead use () => {} so that the this reference is kept valid.

Otherwise you have to use (function() {}).bind(this) to keep this.

  .on('success.form.bv', (e) => {
    // ......
    this.createPost(result, $form);
  });

Upvotes: 0

Related Questions