Comparing version 3.2.0 to 3.3.0
@@ -107,4 +107,6 @@ import * as express from 'express'; | ||
export type ResultExecuteNextFunction = (err?: any, str?: string) => void; | ||
export interface Result { | ||
execute(res: express.Response, next?: express.NextFunction): void; | ||
execute(res: express.Response, next?: ResultExecuteNextFunction): void; | ||
} | ||
@@ -149,3 +151,3 @@ | ||
export type Send = (result: Result) => void; | ||
export type Send = (result: Result, onComplete?: () => (void | Promise<void>)) => void; | ||
} | ||
@@ -152,0 +154,0 @@ |
{ | ||
"name": "goa", | ||
"version": "3.2.0", | ||
"version": "3.3.0", | ||
"description": "A tiny and simple MVC framework for use with Express", | ||
@@ -11,5 +11,2 @@ "keywords": [ | ||
"license": "MIT", | ||
"directories": { | ||
"lib": "src" | ||
}, | ||
"files": [ | ||
@@ -16,0 +13,0 @@ "index.js", |
@@ -176,9 +176,9 @@ # Goa | ||
this.db.insert(record, (err, result) => { | ||
if (err) { | ||
send(goa.error(err)); | ||
return; | ||
} | ||
if (err) { | ||
send(goa.error(err)); | ||
return; | ||
} | ||
send(goa.redirect(`/edit/${result.id}`)); | ||
}); | ||
send(goa.redirect(`/edit/${result.id}`)); | ||
}); | ||
} | ||
@@ -225,20 +225,20 @@ | ||
this.db.insert(record, (err, result) => { | ||
if (err) { | ||
send(goa.error(err)); | ||
return; | ||
} | ||
if (err) { | ||
send(goa.error(err)); | ||
return; | ||
} | ||
send(goa.redirect(`/edit/${result.id}`)); | ||
}); | ||
send(goa.redirect(`/edit/${result.id}`)); | ||
}); | ||
} | ||
public async savePromise(params: goa.ActionParams<SaveParams>, send: goa.Send) { | ||
try { | ||
const record: any = { content: params.content }; | ||
const result = await this.db.insert(record); | ||
send(goa.redirect(`/edit/${result.id}`)); | ||
} catch (e) { | ||
send(goa.error(e)); | ||
} | ||
} | ||
try { | ||
const record: any = { content: params.content }; | ||
const result = await this.db.insert(record); | ||
send(goa.redirect(`/edit/${result.id}`)); | ||
} catch (e) { | ||
send(goa.error(e)); | ||
} | ||
} | ||
} | ||
@@ -262,2 +262,39 @@ ``` | ||
#### Hooking into rendering process | ||
The `send` argument also accepts an `onComplete` callback: | ||
```javascript | ||
{ | ||
myAction: (params, send) => { | ||
const renderStart = Date.now(); | ||
send(goa.view('some/view', { hello: 'world' }), (err) => { | ||
if (err) { | ||
console.error(`rendering encountered an error: ${err.message}`); | ||
} | ||
const renderElapsed = Date.now() - renderStart; | ||
console.log(`rendering took ${renderElapsed}ms`); | ||
}); | ||
} | ||
} | ||
``` | ||
Note that any errors thrown from the `onComplete` callback will be ignored. | ||
The `onComplete` callback can return a promise. Note that the promise will resolve | ||
_before_ sending the response back to the client, so it's not recommended to perform | ||
any heavy tasks inside the `onComplete` callback as it can hide slowness from the | ||
normal program flow. Errors resulting from a rejected promise are ignored. | ||
```javascript | ||
{ | ||
myAction: (params, send) => { | ||
const renderStart = Date.now(); | ||
send(goa.view('some/view', { hello: 'world' }), async (err) => { | ||
const renderElapsed = Date.now() - renderStart; | ||
await db.execute('INSERT INTO render_times (timestamp, elapsed) VALUES (?, ?)', Date.now(), renderElapsed); | ||
}); | ||
} | ||
} | ||
``` | ||
### Putting it all together | ||
@@ -264,0 +301,0 @@ So, to set up your routes to use the controller above, you would do something like this: |
@@ -36,3 +36,3 @@ const http = require('http'); | ||
const runAction = (actionName) => { | ||
const actionResult = controller[actionName](params, function(result) { | ||
const actionResult = controller[actionName](params, function(result, onComplete) { | ||
if (!result || !result.execute) { | ||
@@ -44,8 +44,25 @@ next(new Error(`Action "${controllerName}.${action}" does not return a result object`)); | ||
result.execute(res, (err, str) => { | ||
if (err) { | ||
next(err); | ||
return; | ||
let onCompletePromise; | ||
if (typeof(onComplete) === 'function') { | ||
try { | ||
onCompletePromise = onComplete(err, str); | ||
} catch (err) { | ||
// ignore errors | ||
} | ||
} | ||
res.send(str); | ||
const sendResponse = () => { | ||
if (err) { | ||
next(err); | ||
return; | ||
} | ||
res.send(str); | ||
}; | ||
if (onCompletePromise && typeof(onCompletePromise.then) === 'function') { | ||
onCompletePromise.then(sendResponse).catch(sendResponse); | ||
} else { | ||
sendResponse(); | ||
} | ||
}); | ||
@@ -52,0 +69,0 @@ }); |
24809
408
315