Server side JS are executed inside an asynchronous function, and support the use of await and can return every javascript value or a Promise.
You are not forced to return a string, the server will arrange to return the data with the correct content type.
Here are some examples:
Script returning JSON
const x = {success: false, someData = [1,2,3]}
return x;
Working with Promise
A backend script can return a Promise directly, Anacleto takes care of managing the promis'sthen
const queryArgs = {
db: "MASTER",
sql: "select id from table"
}
return mysql.query(queryArgs);
Promise
In Anacleto all asynchronous methods work using Promises, otherwise it's a moment to end up in the callback hell 😈
Here are some examples of scripts that use promises.
In a script you can use await to wait for the outcome of a promise. Don't worry, wait doesn't block the application because your script is run inside an async function
const queryArgs = {
db: "MASTER",
sql: "select id from table"
}
const ret = await mysql.query(queryArgs);
//work with ret
console.log(ret);
const myRet = ret.map(row =>{
return row.id
})
return myRet;
Use then and catche to handle asynchronous functions
const queryArgs = {
db: "MASTER",
sql: "select id from table"
}
return mysql.query(queryArgs)
.then((res) => {
//work with ret
console.log(ret);
return new Promise((resolve, reject) => {
const myRet = ret.map(row =>{
return row.id
})
resolve(myRet);
});
});
Compact way
const queryArgs = {
db: "MASTER",
sql: "select id from table"
}
return mysql.query(queryArgs)
.then((res) => {
//work with ret
console.log(ret);
const myRet = ret.map(row =>{
return row.id
})
return Promise.resolve(myRet);
});
And when things get serious
let query1Res = [];
let query2Res = [];
return mysql.query(args1)
.then((res) => {
query1Res = res;
//work with res
return mysql.query(args2);
})
.then((res) => {
query2Res = res;
//work with res
return Promise.resolve(res);
})
.catch((error) => {
query2Res = res;
//work with res
return Promise.resolve(res); //or reject
})
Remember, Promise are your friends!
Organize scripts
Folder
In Anacleto you can group scripts in folders, use this feature to better organize and order your code.
May the force be with you
Import
In a backend script you can use the import keyword to import another script. Use this feature when you have code you want to reuse.
Don't worry if some scripts import the same scripts or if some scripts import each other. Anacleto will manage the dependencies for you avoiding recursively importing the same script several times.
Remember that in Anacleto you can organize your scripts in folders and you can do multiple imports. Combine these 2 features to write clean, non-duplicate, and well-organized code.
var declarations are globally scoped or function scoped while let and const are block scoped.
var variables can be updated and re-declared within its scope; let variables can be updated but not re-declared; const variables can neither be updated nor re-declared.
They are all hoisted to the top of their scope. But while var variables are initialized with undefined, let and const variables are not initialized.
While var and let can be declared without being initialized, const must be initialized during declaration.
Strings and ES6
With the advent of ES6 in 2015 working with strings has become much easier.
As you once did:
var nome = "Mario";
var cognome = "Rossi"
var messaggio = "Benvenuto " + nome + " " + cognome;
console.log(messaggio); // Benvenuto Mario Rossi
how you can do it from 2015:
const nome = `Mario`;
const cognome = `Rossi`
const messaggio = `Benvenuto ${nome} ${cognome}`;
console.log(messaggio); // Benvenuto Mario Rossi
TIPS: don't know how to do this strange superscript ` in a Mac? Just press ALT+ BACKSLASH
Date and Numbers
Intl, localize dates and numers
With the advent of ECMAScript all modern browsers and NodeJS support using Intl, this new object can help you a lot in formatting dates and numbers.
//use browser language
Intl.DateTimeFormat(navigator.language, { weekday: 'long', month: 'short', day: 'numeric' }).format(new Date()) // Friday, Dec 27
//specify language
Intl.DateTimeFormat("it", { weekday: 'long', month: 'short', day: 'numeric' }).format(new Date()) // venerdì 19 ago
Intl.DateTimeFormat("en", { weekday: 'long', month: 'short', day: 'numeric' }).format(new Date()) // Friday, Aug 19
const number = 123456.789;
console.log(new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(number));
// expected output: "123.456,79 €"
// the Japanese yen doesn't use a minor unit
console.log(new Intl.NumberFormat('ja-JP', { style: 'currency', currency: 'JPY' }).format(number));
// expected output: "ï¿¥123,457"
// limit to three significant digits
console.log(new Intl.NumberFormat('en-IN', { maximumSignificantDigits: 3 }).format(number));
// expected output: "1,23,000"
TIPS: don't hit your head when you define the formats, let the browser do this job!
Date vs luxon
Working with dates is never easy, anyone who has worked in JS will surely have struggled with the Date object. Unfortunately this object is very basic and just parsing or printing a date is a battle.
For this reason Intl was introduced with ECMAScript which helps us in printing.
Luxon is the heir of moment.js, the moment.js team itself recommends switching to luxon. If you don't know what moment.js is, just know that it was the most used library for working with dates in Javascript
//change date format
DateTime.fromSQL("2017-05-15").toFormat('yyyy LLL dd');
//create a date
const dt = DateTime.local(2017, 5, 15, 8, 30);
//current date
const now = DateTime.now();
//object to date
dt = DateTime.fromObject({day: 22, hour: 12 }, { zone: 'America/Los_Angeles', numberingSystem: 'beng'})
//parse date
DateTime.fromISO("2017-05-15") //=> May 15, 2017 at midnight
DateTime.fromISO("2017-05-15T08:30:00") //=> May 15, 2017 at 8:30
DateTime.fromRFC2822("Tue, 01 Nov 2016 13:23:12 +0630");
DateTime.fromHTTP("Sunday, 06-Nov-94 08:49:37 GMT");
DateTime.fromHTTP("Sun, 06 Nov 1994 08:49:37 GMT");
//parse sql date
DateTime.fromSQL("2017-05-15");
DateTime.fromSQL("2017-05-15 09:24:15");
DateTime.fromSQL("09:24:15");
//parse timestamp
DateTime.fromMillis(1542674993410);
DateTime.fromSeconds(1542674993);
//formato custom
DateTime.fromFormat("May 25 1982", "LLLL dd yyyy");
//date to string
DateTime.now().toString(); //=> '2017-09-14T03:20:34.091-04:00'
dt.toISO(); //=> '2017-04-20T11:32:00.000-04:00'
dt.toISODate(); //=> '2017-04-20'
dt.toISOWeekDate(); //=> '2017-W17-7'
dt.toISOTime(); //=> '11:32:00.000-04:00'
dt.toMillis(); //=> 1492702320000
dt.toSeconds(); //=> 1492702320.000
dt.valueOf(); //=> 1492702320000, same as .toMillis()
dt.toLocaleString(); //=> '4/20/2017'
dt.toLocaleString(DateTime.DATETIME_FULL); //=> 'April 20, 2017, 11:32 AM EDT'
dt.setLocale('fr').toLocaleString(DateTime.DATETIME_FULL); //=> '20 avril 2017 à 11:32 UTC−4'
dt.toFormat('yyyy LLL dd');
//math operation
var dt = DateTime.now();
dt.plus({ hours: 3, minutes: 2 });
dt.minus({ days: 7 });
dt.startOf('day');
dt.endOf('hour');
//properties
dt = DateTime.now();
dt.year //=> 2017
dt.month //=> 9
dt.day //=> 14
dt.second //=> 47
dt.weekday //=> 4
dt.zoneName //=> 'America/New_York'
dt.offset //=> -240
dt.daysInMonth //=> 30
The Intl object is the namespace for the ECMAScript Internationalization API, which provides language sensitive string comparison, number formatting, and date and time formatting. The Intl object provides access to several constructors as well as functionality common to the internationalization constructors and other language sensitive functions.
If this object is not enough for you in Anacleto it is possible to use .
Here are some examples of how Luxon can help you, you can find much more info directly in the official doc -