question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Updating code to Promises to comply with 4.0

See original GitHub issue

Hello,

I am a bit new to Promises and I am struggling to update my code for the future version of alexa-app. Here is an intent I would like to update for example. I am currently use alexa-app 3.2.0. Could you share your input to help me on this? Thanks a lot!

app.launch(function(request, response) {
	var accessTokenReceived = request.sessionDetails.accessToken;
	async.waterfall([
		// STEP 1: check the accessToken
		function(callback) {
			if (accessTokenReceived === undefined) {
				callback('no_access_token');
			}else{
				user.getUserFromAccessTokenPromise(accessTokenReceived).then(function(user) {
					callback(null,user);
				}, function(err){
					var obj = {};
					callback("not_good_access_token");
				});
			}
		},
		//STEP 2 : check stuff
		function(user,  callback) {
			stuff.getStuffFromUserPromise(user).then(function(stuff){
				callback(null, stuff, user, userId);
			},function(err){
				callback("no_stuff");
			});
		},
		function(stuff, user, userId, callback) {
			helper.getStaffUserIdPromise(userId).then(function(staff){
				if (numberOfStaff !== 0) {
					response.say(config.dialog.onLaunchIntent.case13.say);
					response.reprompt(config.dialog.onLaunchIntent.case13.reprompt);
					response.card(config.dialog.onLaunchIntent.case13.cardTitle, config.dialog.onLaunchIntent.case12.card);
					response.shouldEndSession(config.dialog.onLaunchIntent.case13.end);
					response.send();
					callback(null, stuff, user, userId, staff);
				} else {
					callback("no_staff");
				}
			}, function(err){
				callback("error_retrieving_staff");
			});
		},
	], function (err, stuff, user, userId, staff) {
		if(err){
			switch (err) {
				case "no_access_token":
				response.say(config.dialog.onLaunchIntent.case10.say);
				response.reprompt(config.dialog.onLaunchIntent.case10.reprompt);
				response.linkAccount();
				response.shouldEndSession(config.dialog.onLaunchIntent.end);
				response.send();
				break;
				case "not_good_access_token":
				response.say(config.dialog.onLaunchIntent.case10.say);
				response.reprompt(config.dialog.onLaunchIntent.case10.reprompt);
				response.linkAccount();
				response.shouldEndSession(config.dialog.onLaunchIntent.case10.end);
				response.send();
				break;
				case "no_stuff":
				response.say(config.dialog.onLaunchIntent.case11.say);
				response.reprompt(config.dialog.onLaunchIntent.case11.reprompt);
				response.card(config.dialog.onLaunchIntent.case11.cardTitle, config.dialog.onLaunchIntent.case11.card);
				response.shouldEndSession(config.dialog.onLaunchIntent.case11.end);
				response.send();
				break;
				case "no_staff":
				response.say(config.dialog.onLaunchIntent.case12.say);
				response.reprompt(config.dialog.onLaunchIntent.case12.reprompt);
				response.card(config.dialog.onLaunchIntent.case12.cardTitle, config.dialog.onLaunchIntent.case12.card);
				response.shouldEndSession(config.dialog.onLaunchIntent.case12.end);
				response.send();
				break;
				default:
				response.say(config.dialog.onLaunchIntent.case6.say);
				response.reprompt(config.dialog.onLaunchIntent.case6.reprompt);
				response.card(config.dialog.onLaunchIntent.case6.cardTitle, config.dialog.onLaunchIntent.case6.card);
				response.shouldEndSession(config.dialog.onLaunchIntent.case6.end);
				response.send();
			}
		}
	});
	return false;
});

Issue Analytics

  • State:closed
  • Created 7 years ago
  • Comments:6

github_iconTop GitHub Comments

2reactions
dblockcommented, Mar 10, 2017

I have a bunch of tests in https://github.com/artsy/elderfield, and some explanation in http://artsy.github.io/blog/2016/11/30/bringing-artsy-to-amazon-echo-alexa/.

Most of our tests look like this:

chai = require('chai');
expect = chai.expect;
chai.use(require('chai-string'));
chai.use(require('chai-http'));

var server = require('../server');

describe('artsy alexa', function() {
    it('tells me about Norman Rockwell', function(done) {
        var aboutIntentRequest = require('./AboutIntentRequest.json');
        chai.request(server)
            .post('/alexa/artsy')
            .send(aboutIntentRequest)
            .end(function(err, res) {
                expect(res.status).to.equal(200);
                var data = JSON.parse(res.text);
                expect(data.response.outputSpeech.type).to.equal('SSML')
                var ssml = data.response.outputSpeech.ssml;
              expect(ssml).to.startWith('<speak>American artist Norman Rockwell ');
              done();
            });
    });
});
1reaction
ajcritescommented, Mar 1, 2017

I think that you may want to stick with using 3.2 as updating your current style will be quite a bit of refactoring. There are some issues in your code (probably just a result of copy/pasting) so this won’t work out of the box, but it is a close analog. The point of promises is to try to keep things to a single chain.

Ideally you would only need one catch and you could derive the actual error from the caught value, i.e. the error you get from getUserFromAccessTokenPromise or getStuffFromUserPromise would be different and you could look at that value in the error in the final catch rather than catching each individual error returned by that promise and then throwing a separate error. If these errors exist throughout your app, consider using app.error to handle them as well as it is also part of the app’s promise chain.

Note that using response.send() is not needed since it gets called automatically when the promise chain resolves.

Example that should work with your existing code: https://gist.github.com/ajcrites/3dbb77998f33ef9f0700bd4f5f748b07

Ideal example (your promise functions throw corresponding error messages): https://gist.github.com/ajcrites/323dc219b588ca7f76c24afe95d03078

Read more comments on GitHub >

github_iconTop Results From Across the Web

How do I convert an existing callback API to promises?
I'm wanting to wrap all my synchronous Noje.js functions in a Promise so as to remove all synchronous code from my Node app,...
Read more >
Understanding the Event Loop, Callbacks, Promises, and ...
Promises have a method called then that will run after a promise reaches resolve in the code. then will return the promise's value...
Read more >
'request' with Promise - GitHub
By default, http response codes other than 2xx will cause the promise to ... Also check out the new libraries that are very...
Read more >
Promises and Callbacks — Node.js - MongoDB
The following code snippet shows an example of Promise chaining by appending a single then() ... res => console.log(`Updated ${res.result.n} documents`),.
Read more >
Issues you may meet when upgrading Azure function app to V4
This blog will talk about some common issues you may meet when you try to upgrade your Azure function from older runtime version...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found