Tell me more ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I'm new to typescript and angular.js and I'm struggling with a http get request. I'm using DefinitelyTyped for angular's type definitions.

My controller code looks like this:

module game.Controller {
    'use strict';

    export interface IGameScope extends ng.IScope {
        vm: GameCtrl;
    }

    export class GameCtrl {

        private bonus: any;
        private http: any;

        constructor($scope: IGameScope, $http: ng.IHttpService, $location: ng.ILocationService) { 
            $scope.vm = this;
            this.http = $http;
        }

        doBet() {
            this.http.get('http://localhost:9000/db').success(function(data: any, status: any) { 
                    this.bonus = data;
                }
            );
        }
    }

}

and my view like this:

<button ng-click="vm.doBet()">bet</button>
<div><span>bonus: {{ vm.bonus }}</span></div>

the view-model binding works fine, when I change the bonus variable without the http request. But when I try to update the bonus variable in the success function of the get request, I get following error:

TypeError: Cannot set property 'bonus' of undefined

How can I achieve to update variables in the success function?

I also would appreciate any suggestion, if there's a better/cleaner way or practice to update data on requests

share|improve this question

4 Answers

this in this.bonus = data; actually refers to the callback function inside success.

Instead you can do like this: $scope.vm.bonus = data;

share|improve this answer
 
this doesn't work, since $scope is only visible in constructor and not in the doBet() function. –  3x14159265 Aug 15 at 13:33
1  
@3x14159265 Move doBet() into your constructor and declare it as a method on $scope: $scope.doBet = function() { ... };, or simply pass $scope into doBet(). –  André Dion Aug 15 at 13:35
 
@3x14159265 Of the 2 options, I would preferably move doBet inside the controller and declare it on the scope. –  CodeHater Aug 15 at 13:39

I haven't used typescript, but to me it looks like a closure/scope issue. Your success call back is running asynchronously so the value of this is different inside. Try binding the function call back with this.

this.http.get('http://localhost:9000/db').success(angular.bind(this,
    function(data: any, status: any) {this.bonus = data;});
share|improve this answer
 
This is not necessary in typescript. See 3x14159265's answer. –  rob Aug 15 at 21:14
up vote 1 down vote accepted

This can easily be done using TypeScript's lambda expression:

doBet() {
    this.http.get('http://localhost:9000/db').success(
        (data, status) => this.bonus = data
    );
}
share|improve this answer

You can put the method in the constructor in order to access the $scope like this:

constructor($scope: IGameScope, $http: ng.IHttpService, $location: ng.ILocationService) {
    $scope.vm = this;
    this.http = $http;

    $scope.doBet = function() {
        this.http.get('http://localhost:9000/db').success(function (data: any, status: any) {
            $scope.bonus = data;
        });
    }
}

Here is a tutorial about using AngularJS with Typescript.

share|improve this answer
 
thanks, I already read this tutorial. But is it really best practice to define all scope functions in the controller? furthermore, I'm binding the $scope.vm variable to my controller instance to omitte the need of binding every single scope variable to my controller variables. so IMHO in this case, there would be no enhancement on using the binding $scope.vm = this;. –  3x14159265 Aug 15 at 14:03
 
@3x14159265 I think it is really over killing to use TypeScript, it complicated the JavaScript. –  sza Aug 15 at 14:08

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.