0

Here's the code that I have:

resolve: {
            get: ['setTest', 'questionService', 'testService', '$stateParams',
                (setTest, qus: IQuestionService, tes: ITestService, $stateParams) => {
                    if (tes.qs) {
                        qus.mapUserTestQuestions(tes.qs);
                        return true;
                    } else {
                        var userTestId = parseInt($stateParams.testId.substring(6, 11));
                        return qus.getUserTestQuestions(userTestId);
                    }
                }]
        },

The problem is that I get a message saying "No common return type" which I guess is because one part of the if returns true and the other a promise.

BrTkCa
  • 4,703
  • 3
  • 24
  • 45
Alan2
  • 23,493
  • 79
  • 256
  • 450
  • It's more a design problem that a technical problem. Why is a single variable (`get`) either a boolean or (I guess) an array of questions? – JB Nizet Mar 01 '16 at 18:19
  • 1
    You should return a promise in the `resolve` part. Use `$q.reject()` and `$q.resolve()`. – ssc-hrep3 Mar 01 '16 at 18:19
  • See [TypeScript type casting](http://stackoverflow.com/questions/13204759/typescript-or-javascript-type-casting). That is a TypeScript casting error. Your code will work in vanilla JavaScript (albiet wierdly). – georgeawg Mar 01 '16 at 18:56

2 Answers2

2

In most cases there should be a better solution than returning a boolean value synchronously vs. a promise of some questions. This also leads to some more decision logic on the controller that probably could be avoided.

It seems that in the first case, you already have the required data and do not need to perform any async calls. So why not just returning this (synchronously) transformed data via a promise (assuming the result of mapUserTestQuestions and getUserTestQuestions is of the same type. If so, just wrap the result using the $q service like so:

return $q.when(qus.mapUserTestQuestions(tes.qs));

This way you can access you data the same way, no matter if it was already there or you needed to do some async call. For $q see: https://docs.angularjs.org/api/ng/service/$q#when

Andreas Jägle
  • 11,632
  • 3
  • 31
  • 31
1

TypeScript 1.4 added Union Types which allows a variable be annotated with a list of types:

let myVar: boolean|string;

// both of these are valid assignments
myVar = true;
myVar = 'hello world';

You can also apply this to the return type of your function, like so:

resolve: {
    get: ['setTest', 'questionService', 'testService', '$stateParams',
        (setTest, qus: IQuestionService, tes: ITestService, $stateParams): boolean|Promise => {
            if (tes.qs) {
                qus.mapUserTestQuestions(tes.qs);
                return true;
            } else {
                var userTestId = parseInt($stateParams.testId.substring(6, 11));                    
                return qus.getUserTestQuestions(userTestId);
            }
        }]
},

Note the boolean|Promise type annotation on the return type of the anonymous function.

Nathan Friend
  • 12,155
  • 10
  • 75
  • 125