📑 In This Module
🎯 Learning Objectives
By the end of this module, you will be able to:
- Understand what SuiteScript modules are and why they're used
- Load modules correctly using the define() statement
- Use N/record to load, create, and transform records
- Work with other essential modules (N/email, N/runtime, N/url)
- Understand synchronous vs asynchronous operations with promises
1. What Are SuiteScript Modules?
Modules are libraries of functionality that you add to your scripts. Think of them as toolboxes - you only bring the tools you need for the job.
In SuiteScript 1.0, all functions were in the global scope, using memory for capabilities you might never use. SuiteScript 2.x modules let you load only what you need, making scripts more efficient and maintainable.
Module Naming Convention
NetSuite modules start with N/ to indicate they're built-in NetSuite APIs:
N/record- Work with recordsN/search- Create and run searchesN/email- Send emailsN/runtime- Get script/user infoN/log- Logging (auto-loaded)
2. Loading Modules with define()
Basic Syntax
/**
* @NApiVersion 2.1
* @NScriptType UserEventScript
*/
define(['N/record', 'N/email', 'N/runtime'], function(record, email, runtime) {
// Now you can use record.load(), email.send(), runtime.getCurrentUser()
function afterSubmit(context) {
// Your code here
}
return { afterSubmit: afterSubmit };
});
The order of modules in the array must match the order of parameters in the callback function. If you list ['N/record', 'N/email'], your function must be function(record, email) - not function(email, record).
Variable Naming
You can name the variables anything, but convention is to use the module name:
// Standard (recommended)
define(['N/record'], function(record) { ... });
// Also valid, but non-standard
define(['N/record'], function(rec) { ... });
define(['N/record'], function(recordModule) { ... });
3. The N/record Module
The N/record module is essential for working with NetSuite records programmatically.
Loading a Record
var customerRecord = record.load({
type: record.Type.CUSTOMER, // or 'customer'
id: 123,
isDynamic: false // Static mode (default)
});
// Now read/modify the record
var name = customerRecord.getValue('companyname');
customerRecord.setValue('phone', '555-1234');
customerRecord.save();
Creating a Record
var phoneCall = record.create({
type: record.Type.PHONE_CALL,
isDynamic: true
});
phoneCall.setValue('title', 'Follow-up call');
phoneCall.setValue('phone', '555-1234');
var newId = phoneCall.save();
log.debug('Created Phone Call', 'ID: ' + newId);
Transforming Records
Transform creates a new record from an existing one, copying relevant values:
// Create Invoice from Sales Order
var invoice = record.transform({
fromType: record.Type.SALES_ORDER,
fromId: 456,
toType: record.Type.INVOICE
});
var invoiceId = invoice.save();
Dynamic vs Standard Mode
| Feature | Standard Mode | Dynamic Mode |
|---|---|---|
| Field sourcing | Manual | Automatic |
| Sublist editing | By line number | Select → Edit → Commit |
| Performance | Faster | Slower |
| Use case | Bulk operations | UI-like behavior |
Use Standard mode (isDynamic: false) for server-side scripts processing multiple records. Use Dynamic mode (isDynamic: true) when you need automatic field sourcing or are simulating UI behavior.
4. Other Common Modules
N/email - Send Emails
define(['N/email'], function(email) {
email.send({
author: 123, // Employee internal ID
recipients: 'user@example.com',
subject: 'Order Confirmation',
body: 'Thank you for your order!'
});
});
N/runtime - Script & User Context
define(['N/runtime'], function(runtime) {
// Get current user info
var user = runtime.getCurrentUser();
log.debug('User', user.name + ' (ID: ' + user.id + ')');
// Get current script info
var script = runtime.getCurrentScript();
log.debug('Remaining Governance', script.getRemainingUsage());
// Get script parameters
var paramValue = script.getParameter('custscript_my_param');
});
N/url - Generate URLs
define(['N/url'], function(url) {
// URL to a record
var recordUrl = url.resolveRecord({
recordType: 'customer',
recordId: 123,
isEditMode: false
});
// URL to a Suitelet
var suiteletUrl = url.resolveScript({
scriptId: 'customscript_my_suitelet',
deploymentId: 'customdeploy_my_suitelet',
params: { custparam_id: 456 }
});
});
N/format - Date/Number Formatting
define(['N/format'], function(format) {
// Parse a date string to Date object
var dateObj = format.parse({
value: '12/25/2024',
type: format.Type.DATE
});
// Format a Date object to string
var dateStr = format.format({
value: new Date(),
type: format.Type.DATETIME
});
});
Common Modules Reference
| Module | Purpose | Key Functions |
|---|---|---|
N/record | Record CRUD | load, create, delete, transform |
N/search | Searching | create, load, lookupFields |
N/email | send, sendBulk | |
N/runtime | Context info | getCurrentUser, getCurrentScript |
N/url | URL building | resolveRecord, resolveScript |
N/format | Formatting | parse, format |
N/file | File Cabinet | create, load, delete |
N/http | HTTP calls | get, post, request |
N/redirect | Page redirect | toRecord, toSuitelet |
5. Promises in SuiteScript
Some operations have .promise() versions for asynchronous execution:
// Synchronous (blocks until complete)
var rec = record.load({
type: 'customer',
id: 123
});
log.debug('Loaded', rec.getValue('companyname'));
// Asynchronous (returns promise)
record.load.promise({
type: 'customer',
id: 123
}).then(function(rec) {
log.debug('Loaded', rec.getValue('companyname'));
}).catch(function(error) {
log.error('Load Failed', error.message);
});
Promises are useful in client scripts where you don't want to freeze the UI while waiting for server responses. In server-side scripts, synchronous calls are usually simpler and sufficient.
🏋️ Practice Exercises
Create a User Event script that loads a related Customer record when a Sales Order is saved, and logs the customer's email address.
When a new Employee is created, automatically create a Phone Call record assigned to them with subject "HR Onboarding Call".
Create an afterSubmit script that sends an email to the sales rep when a Sales Order total exceeds $10,000.
🎯 Key Takeaways
- Modules are loaded via
define(['N/module'], function(module) {...}) - Array order must match function parameter order
N/recordprovides load(), create(), transform(), delete()- Use standard mode for performance, dynamic mode for UI-like behavior
- Always pass parameters as objects:
{ type: 'customer', id: 123 } - Check Help Center for full module documentation