3

So far, the suggestions I've seen to remedy my issue don't seem to apply, or I have a big misunderstanding (I haven't touched full stack in quite a while). I've got a service that successfully hits a Spring Boot backend to get a list of processes:

function getReportProcesses(){
        var deferred =  $q.defer();
        var url = "fermentationReports/processes";
        httpService.get(url).then(function (data){
            deferred.resolve(data);
        }, function(msg){
            var errMsg  = "failed to get report processes: " +  msg;
            deferred.reject(errMsg);
        });
        return deferred.promise;
    }

My objective is to hit the service from a dropdown factory, turn the list into JSON, and pass it to the dropdown as populated by the dropdown directive. When the directive calls the following line to get the JSON:

var data = ReportDdlFactory.getReportName();
            addAllTo(data, $scope.addAll);

it doesn't wait for the httpService in getReportName() to return before adding data as undefined to the scope. This is the original method in the factory:

function getReportName() {

            try {
                FermentationReportsService.getReportProcesses().then(function (data) {
                    if (data.processes !== undefined) {

                        var output = {"data": []};
                        for (var i = 0; i < data.processes.length; i++) {
                            var currentLine = {"value": data.processes[i], "label": data.processes[i]};
                            output.data.push(currentLine);
                        }
                        return output;

                    } else {
                        return {
                            "data": [
                                {"value": "ERROR OBTAINING PROCESSES", "label": "ERROR OBTAINING PROCESSES"}]
                        };
                    }
                });
            } catch (err) {
                console.log("error caught: " + err);
            }
        }

I tried to change it to use async/await since getReportProcesses() already returns a promise:

async getReportName() {

            try {
                await FermentationReportsService.getReportProcesses().then(function (data) {
                    if (data.processes !== undefined) {

                        var output = {"data": []};
                        for (var i = 0; i < data.processes.length; i++) {
                            var currentLine = {"value": data.processes[i], "label": data.processes[i]};
                            output.data.push(currentLine);
                        }
                        return output;

                    } else {
                        return {
                            "data": [
                                {"value": "ERROR OBTAINING PROCESSES", "label": "ERROR OBTAINING PROCESSES"}]
                        };
                    }
                });
            } catch (err) {
                console.log("error caught: " + err);
            }
        }

But I always get this from jshint:

 14 |            async getReportName() {
                 ^ Expected an assignment or function call and instead saw an expression.
 14 |            async getReportName() {
                      ^ Missing semicolon.
 14 |            async getReportName() {
                                      ^ Missing semicolon.
 17 |                    await FermentationReportsService.getReportProcesses().then(function (data) {
                         ^ Expected an assignment or function call and instead saw an expression.
 17 |                    await FermentationReportsService.getReportProcesses().then(function (data) {
                              ^ Missing semicolon.
  8 |                getReportName: getReportName,
                                    ^ 'getReportName' is not defined.
 14 |            async getReportName() {
                       ^ 'getReportName' is not defined.
 14 |            async getReportName() {
                 ^ 'async' is not defined.

I feel like I may be making this harder than it needs to be, or maybe I'm missing something simple?


EDIT:

After more research I determined that the app is running as 'strict', forcing ECMA 5. Is there an approach to force the response before continuing without using an ES6 approach?

6
  • You still need the function keyword when making it async. That being said, your problem in both cases is just that you don't return any value. You need to return FermentationReportsService.getR.... The Promise will then resolve to that value Commented Apr 2, 2021 at 21:16
  • this code it not clear for me so if it possible share a complete version over stackblitz.com 🤔🤔 Commented Apr 2, 2021 at 21:24
  • @blex thanks, I'll test that out. Commented Apr 2, 2021 at 21:29
  • @malbarmavi Sorry, I can't. Most of the code is proprietary and confidential as owned by the company I work for. I even had to obfuscate function names and such to safely post my issue here. Commented Apr 2, 2021 at 21:29
  • @blex when you say to return FermentationReportsService.getR..., I can't do that. It comes as a list, so I need to iterate over them and return the JSON object I created which happens after the for-loop. Does returning the output variable make the process invalid? Commented Apr 2, 2021 at 21:35

2 Answers 2

1

I would probably do something like this:

function getReportName() {
  return FermentationReportsService
    .getReportProcesses()
    .then(function(data) {
      if (data.processes === undefined) {
        return { data: [
          { value: "ERROR OBTAINING PROCESSES", label: "ERROR OBTAINING PROCESSES" }
        ]};
      }
      
      return {
        data: data.processes.map(function(process) {
                return { value: process.value, label: process.value };
              })
      };
    })
    .catch(function(err) {
      console.log("error caught: " + err);
    });
}
Sign up to request clarification or add additional context in comments.

5 Comments

Thanks blex. I did some more digging and determined that this is running as 'strict', using ES5 and so these approaches are apparently disallowed in my position. Do you know of a way that uses ES5 keywords only? Apparently, the arrow, await, async, etc aren't allowed, and jshint doesn't recognize them as legal keywords.
@DarrelHolt I've edited the answer, this should work
The app builds correctly and passes the jshint, but it's still hitting the directive line that adds data to the scope before executing getReportName(). the data object also has this structure: { "$$state": { "status": 0 } }. Should I make the calling method to the getReportName() within the directive async so it waits as well?
Oh yes I forgot this part. This function returns a Promise, so it's asynchronous. You'll need to do something along these lines: ReportDdlFactory.getReportName().then(function(data) { addAllTo(data, $scope.addAll); });
Thanks, you got it. there were a few more methods called that used the data variable in the directive so I put those in the then method and it works perfectly.
1

by using async/await you no longer need to use then

async function getReportName() {
  try {
    const data = await FermentationReportsService.getReportProcesses();
    if (data.processes !== undefined) {
      var output = { data: [] };
      for (var i = 0; i < data.processes.length; i++) {
        var currentLine = {
          value: data.processes[i],
          label: data.processes[i],
        };
        output.data.push(currentLine);
      }
      return output;
    } else {
      return {
        data: [
          {
            value: 'ERROR OBTAINING PROCESSES',
            label: 'ERROR OBTAINING PROCESSES',
          },
        ],
      };
    }
  } catch (err) {
    console.log('error caught: ' + err);
  }
}

check this article for more info 👉 javascript.info async/await

3 Comments

Thanks, I'm seeing that my jshint is still complaining. First, it's saying this about async in the function header: Expected an assignment or function call and instead saw an expression. Followed by async is not defined. As well as 'const' is available in ES6. Is async something that needs to be defined or included in the module factory header? Also it want a semicolon after await on the line const data = await FermentationReportsService.getReportProcesses();
is getReportName part of class ? if so you need to remove the function keyword but I'm not sure because you don't share the full source of the component in case you are using angular 😕😕
Thank you guys for your help thus far. I did some more digging and determined that this is running as 'strict', using ES5 and so these approaches are apparently disallowed in my position. Do you know of a way that uses ES5? Apparently, the arrow, await, async, etc aren't allowed and jshint doesn't recognize them as legal keywords.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.