{"revision":"c10276e953456835cdbb1f3a60d58ae1980be353","document":{"id":861,"path":"api-reference/server-api-reference/OptionalGlobalAPI.md","title":"Optional - Scoped, Global","bundle":null,"doc_type":null,"release":"australia","body":"\n# Optional - Scoped, Global\n\nThe Optional API interacts with a single record returned by the GlideQuery, Stream, or GlideRecord APIs, even when it does not exist. Write scripts that are less likely to result in an error by handling null or undefined query results.\n\nYou can get an Optional object in these ways:\n\n-   Return an Optional object from these methods in the GlideQuery class. For more information, see [GlideQuery](https://raw.githubusercontent.com/ServiceNow/ServiceNowDocs/australia/markdown/australia/api-reference/server-api-reference/GlideQueryGlobalAPI.md).\n    -   [getBy\\(\\)](https://raw.githubusercontent.com/ServiceNow/ServiceNowDocs/australia/markdown/australia/api-reference/server-api-reference/GlideQueryGlobalAPI.md)\n    -   [get\\(\\)](https://raw.githubusercontent.com/ServiceNow/ServiceNowDocs/australia/markdown/australia/api-reference/server-api-reference/GlideQueryGlobalAPI.md)\n    -   [insert\\(\\)](https://raw.githubusercontent.com/ServiceNow/ServiceNowDocs/australia/markdown/australia/api-reference/server-api-reference/GlideQueryGlobalAPI.md)\n    -   [insertOrUpdate\\(\\)](https://raw.githubusercontent.com/ServiceNow/ServiceNowDocs/australia/markdown/australia/api-reference/server-api-reference/GlideQueryGlobalAPI.md)\n    -   [update\\(\\)](https://raw.githubusercontent.com/ServiceNow/ServiceNowDocs/australia/markdown/australia/api-reference/server-api-reference/GlideQueryGlobalAPI.md)\n    -   [selectOne\\(\\)](https://raw.githubusercontent.com/ServiceNow/ServiceNowDocs/australia/markdown/australia/api-reference/server-api-reference/GlideQueryGlobalAPI.md)\n    -   [avg\\(\\)](https://raw.githubusercontent.com/ServiceNow/ServiceNowDocs/australia/markdown/australia/api-reference/server-api-reference/GlideQueryGlobalAPI.md)\n    -   [max\\(\\)](https://raw.githubusercontent.com/ServiceNow/ServiceNowDocs/australia/markdown/australia/api-reference/server-api-reference/GlideQueryGlobalAPI.md)\n    -   [min\\(\\)](https://raw.githubusercontent.com/ServiceNow/ServiceNowDocs/australia/markdown/australia/api-reference/server-api-reference/GlideQueryGlobalAPI.md)\n    -   [sum\\(\\)](https://raw.githubusercontent.com/ServiceNow/ServiceNowDocs/australia/markdown/australia/api-reference/server-api-reference/GlideQueryGlobalAPI.md)\n-   Return an Optional object from the [find\\(\\)](https://raw.githubusercontent.com/ServiceNow/ServiceNowDocs/australia/markdown/australia/api-reference/server-api-reference/StreamGlobalAPI.md) method in the Stream class. For more information on Stream, see the [Stream](https://raw.githubusercontent.com/ServiceNow/ServiceNowDocs/australia/markdown/australia/api-reference/server-api-reference/StreamGlobalAPI.md) API.\n-   Use the [lazy\\(\\)](https://raw.githubusercontent.com/ServiceNow/ServiceNowDocs/australia/markdown/australia/api-reference/server-api-reference/OptionalGlobalAPI.md) method to generate the value of the Optional if ever needed.\n\nThese methods are static and do not require an instance of the class:\n\n-   [lazy\\(\\)](https://raw.githubusercontent.com/ServiceNow/ServiceNowDocs/australia/markdown/australia/api-reference/server-api-reference/OptionalGlobalAPI.md)\n-   [of\\(\\)](https://raw.githubusercontent.com/ServiceNow/ServiceNowDocs/australia/markdown/australia/api-reference/server-api-reference/OptionalGlobalAPI.md)\n-   [empty\\(\\)](https://raw.githubusercontent.com/ServiceNow/ServiceNowDocs/australia/markdown/australia/api-reference/server-api-reference/OptionalGlobalAPI.md)\n\nYou can use these static methods with any API that returns a single value such as [GlideRecord](https://raw.githubusercontent.com/ServiceNow/ServiceNowDocs/australia/markdown/australia/api-reference/server-api-reference/c_GlideRecordScopedAPI.md).\n\nUse the Optional API in scoped or global server-side scripts. This API requires the GlideQuery \\[com.sn\\_glidequery\\] plugin.\n\n## Implementation\n\nThis API can work with the [GlideQuery](https://raw.githubusercontent.com/ServiceNow/ServiceNowDocs/australia/markdown/australia/api-reference/server-api-reference/GlideQueryGlobalAPI.md) and [Stream](https://raw.githubusercontent.com/ServiceNow/ServiceNowDocs/australia/markdown/australia/api-reference/server-api-reference/StreamGlobalAPI.md) APIs in a builder pattern where the method calls chain together, each method building on the returned result of the previous method. Use methods to define the attributes of the query. The methods do not execute until you call a terminal method, a method that returns a query result, allowing you to define the requirements of the query before executing it.\n\nIf the query returns a single record, the system wraps the result in an Optional object. If the query returns a stream of records, the system wraps the result in a Stream object. These objects let you manage the result using a set of methods in each API.\n\nFor example, this script performs a query on the Task table, groups the records by priority, and returns each priority that has total reassignments greater than four.\n\n```\nvar query = new global.GlideQuery('task')\n    .where('active', true) //Returns new GlideQuery object with a \"where\" clause.\n    .groupBy('priority') //Returns new GlideQuery object with a \"group by\" clause.\n    .aggregate('sum', 'reassignment_count') //Returns new GlideQuery object with a \"sum(reassignment_count)\" clause.\n    .having('sum', 'reassignment_count', '>', 4) //Returns new GlideQuery object with a \"having reassignment_count > 4\" clause.\n    .select() //Returns a stream of records wrapped in a Stream object.  \n    .forEach(function (priority){ //Terminal method in the Stream class that executes the query and returns the result. \n      gs.info(\"Priority \" + priority.group.priority + \": \" + priority.sum.reassignment_count + \" reassignments\");\n    });\n```\n\nOutput:\n\n```\nPriority 1: 11 reassignments\nPriority 3: 6 reassignments\nPriority 5: 5 reassignments\n```\n\n## Terminal methods\n\nFor performance reasons, a query only fetches data when you call a terminal method. These are the terminal methods from the Optional class:\n\n-   [get\\(\\)](https://raw.githubusercontent.com/ServiceNow/ServiceNowDocs/australia/markdown/australia/api-reference/server-api-reference/OptionalGlobalAPI.md)\n-   [orElse\\(\\)](https://raw.githubusercontent.com/ServiceNow/ServiceNowDocs/australia/markdown/australia/api-reference/server-api-reference/OptionalGlobalAPI.md)\n-   [ifPresent\\(\\)](https://raw.githubusercontent.com/ServiceNow/ServiceNowDocs/australia/markdown/australia/api-reference/server-api-reference/OptionalGlobalAPI.md)\n-   [isEmpty\\(\\)](https://raw.githubusercontent.com/ServiceNow/ServiceNowDocs/australia/markdown/australia/api-reference/server-api-reference/OptionalGlobalAPI.md)\n-   [isPresent\\(\\)](https://raw.githubusercontent.com/ServiceNow/ServiceNowDocs/australia/markdown/australia/api-reference/server-api-reference/OptionalGlobalAPI.md)\n\n**Parent Topic:**[Server API reference](https://raw.githubusercontent.com/ServiceNow/ServiceNowDocs/australia/markdown/australia/api-reference/server-api-reference/api-server.md)\n\n## Optional - empty\\(String reason\\)\n\nReturns an empty Optional object. Use this method in an Else clause to handle a query that might not return a result.\n\n**Note:** This method is static. You do not need an instance of the class to use this method.\n\n|Name|Type|Description|\n|----|----|-----------|\n|reason|String|Optional. Reason displayed in the log when Optional.get\\(\\) is called on the empty Optional object.|\n\n|Type|Description|\n|----|-----------|\n|Optional|Object used to interact with a single record.|\n\nThis example shows you how to generate an empty Optional object when a query does not return a result.\n\n```\nvar now_GR = new GlideRecord('task');\nnow_GR.addQuery('approval', 'not requested'); \nnow_GR.query();\nvar optional;\nif (now_GR.next()) {\noptional = Optional.of(now_GR.getUniqueValue());\n} else {\n    optional = Optional.empty(\"no results\");\n}\n\ngs.info(optional.get());\n```\n\nOutput:\n\n```\nNiceError: [2020-08-26T23:23:37.402Z]: get() called on empty Optional: no results\n```\n\n## Optional - filter\\(Function predicate\\)\n\nApplies a predicate function, a function that takes a single value and returns true or false, to the record inside the Optional object. If the function returns true, the method returns the Optional record unchanged. If the function returns false, it returns an empty Optional object.\n\n|Name|Type|Description|\n|----|----|-----------|\n|predicate|Function|Predicate function to apply to the value inside the Optional object. Must return a Boolean value.|\n\n|Type|Description|\n|----|-----------|\n|Optional|Object used to interact with a single record.|\n\nThis example shows you how to apply a filter function to an Optional result.\n\n```\nvar filteredQuery = new global.GlideQuery('sys_user')\n    .getBy({ sys_id: 'f682abf03710200044e0bfc8bcbe5d38' }, ['phone'])\n    .filter(function (user) {\n        return phoneRegex.test(user.phone);\n    });\n```\n\n## Optional - flatMap\\(Function fn\\)\n\nApplies a function that returns an Optional object to the result of a query. Use this method to perform a second query using the result of the first.\n\n|Name|Type|Description|\n|----|----|-----------|\n|fn|Function|Function to apply to the results of the query that returned the Optional object.|\n\n|Type|Description|\n|----|-----------|\n|Optional|Object used to interact with a single record.|\n\nThis example shows how to execute a query of the User table based on the result of a previous query.\n\n```\nnew global.GlideQuery('alm_asset')\n    .whereNotNull('owned_by')\n    .selectOne('owned_by')\n    .flatMap(function (asset) {\n        return new global.GlideQuery('sys_user')\n            .getBy({ sys_id: asset.owned_by }, ['first_name', 'last_name', 'company.name'])\n    })\n    .ifPresent(GQ.jsonDebug);\n```\n\nOutput:\n\n```\n{\n  \"sys_id\": \"46d59205a9fe198101d603f5de37bfa3\",\n  \"first_name\": \"John\",\n  \"last_name\": \"Bohnhamn\",\n  \"company\": {\n    \"name\": \"ACME North America\"\n  }\n}\n```\n\n## Optional - get\\(\\)\n\nReturns the record inside the Optional object, or throws an error if the query does not return a record.\n\n|Name|Type|Description|\n|----|----|-----------|\n|None| | |\n\n|Type|Description|\n|----|-----------|\n|Any|The record inside the Optional object. If the value is null or undefined, the system throws an error.|\n\nThis example shows how to get the value of a single record.\n\n```\nvar value = new global.GlideQuery('sys_user')\n    .selectOne('first_name') //Returns the result of the query inside an Optional object\n    .get(); //Calls Optional.get() on the Optional object\n\ngs.info(JSON.stringify(value));\n```\n\nOutput:\n\n```\n{\n   \"first_name\":\"fred\",\n   \"sys_id\":\"005d500b536073005e0addeeff7b12f4\"\n}\n```\n\n## Optional - ifPresent\\(Function fn\\)\n\nApplies a function to the record within an Optional object. If the Optional object does not contain a record, the function does not execute.\n\n|Name|Type|Description|\n|----|----|-----------|\n|fn|Function|The function to apply to the record within the Optional object.|\n\n|Type|Description|\n|----|-----------|\n|None| |\n\nThis example shows how to print a value if it exists.\n\n```\nvar user = new global.GlideQuery('sys_user')\n    .where('sys_id', 'f682abf03710200044e0bfc8bcbe5d38')\n    .selectOne('zip')\n    .ifPresent(function (user) {\n      gs.info('Zip Code: ' + user.zip);\n    });\n```\n\n## Optional - isEmpty\\(\\)\n\nReturns true if the Optional object is empty.\n\n|Name|Type|Description|\n|----|----|-----------|\n|None| | |\n\n<table id=\"table_zhd_b1l_4mb\" class=\"returns\"><thead><tr><th>\n\nType\n\n</th><th>\n\nDescription\n\n</th></tr></thead><tbody><tr><td>\n\nBoolean\n\n</td><td>\n\nFlag that indicates whether the result of a query contains a value.\n\n Valid values:\n\n-   true: The query returns null or undefined.\n-   false: The query returns a value.\n\n</td></tr></tbody>\n</table>This example shows how to check whether the result of a query is empty.\n\n```\nvar checkEmpty = new global.GlideQuery('sys_user')\n    .where('last_name', 'Barker')\n    .selectOne()\n    .isEmpty();\n\ngs.info(checkEmpty);\n```\n\nOutput:\n\n```\ntrue\n```\n\n## Optional - isPresent\\(\\)\n\nChecks whether an Optional object contains a value.\n\n|Name|Type|Description|\n|----|----|-----------|\n|None| | |\n\n<table id=\"table_jcx_c1l_4mb\" class=\"returns\"><thead><tr><th>\n\nType\n\n</th><th>\n\nDescription\n\n</th></tr></thead><tbody><tr><td>\n\nBoolean\n\n</td><td>\n\nFlag that indicates whether the result of a query contains a value.\n\n Valid values:\n\n-   true: The query returns a value.\n-   false: The query returns null or undefined.\n\n</td></tr></tbody>\n</table>This example shows how to check whether a query returns a result.\n\n```\nvar checkPresent = new global.GlideQuery('sys_user')    \n   .where('last_name', 'Luddy')\n   .selectOne('first_name')\n   .isPresent();\n\ngs.info(checkPresent);\n```\n\nOutput:\n\n```\ntrue\n```\n\n## Optional - lazy\\(Function lazyGetFn\\)\n\nReturns a new Optional object. Instead of containing the record, the object contains a function to get the record that is only called if and when requested in the code.\n\nUse this method to delay getting the value until it's needed. You might do this if requesting the value from a slow source and don't want to slow down your code unnecessarily. Otherwise, you can return an Optional object using the [GlideQuery](https://raw.githubusercontent.com/ServiceNow/ServiceNowDocs/australia/markdown/australia/api-reference/server-api-reference/GlideQueryGlobalAPI.md) and [Stream](https://raw.githubusercontent.com/ServiceNow/ServiceNowDocs/australia/markdown/australia/api-reference/server-api-reference/StreamGlobalAPI.md) APIs.\n\n**Note:** This method is static. You do not need an instance of the class to use this method.\n\n<table id=\"table_edm_lwj_5mb\" class=\"parameters\"><thead><tr><th>\n\nName\n\n</th><th>\n\nType\n\n</th><th>\n\nDescription\n\n</th></tr></thead><tbody><tr><td>\n\nlazyGetFn\n\n</td><td>\n\nFunction\n\n</td><td>\n\nFunction that returns a single record as a result of a query. For example: ```\nvar userGr = new GlideRecord('sys_user');\n```\n\n</td></tr></tbody>\n</table>|Type|Description|\n|----|-----------|\n|Optional|Object containing the result of the query in the format `Optional<result>`.|\n\nThis example shows how to get an Optional object based on a GlideRecord query.\n\n```\nvar userOptional = global.Optional.lazy(function () {\n    var userGr = new GlideRecord('sys_user');\n    userGr.setLimit(1);\n    userGr.query();\n    return userGr.next() ? userGr.getUniqueValue() : null;\n});\n\ngs.info(userOptional);\n```\n\nOutput:\n\n```\nOptional<005d500b536073005e0addeeff7b12f4>\n```\n\n## Optional - map\\(Function fn\\)\n\nApplies a function to the result of a query.\n\n|Name|Type|Description|\n|----|----|-----------|\n|fn|Function|Function to apply to the result of the query.|\n\n|Type|Description|\n|----|-----------|\n|Optional|Object containing the results of the query updated by the function in the format `Optional<result>`.|\n\nThis example shows how to apply a function that transforms a value to upper case to the result of a query.\n\n```\nvar value = new global.GlideQuery('sys_user')\n    .whereNotNull('first_name')\n    .selectOne('first_name')\n    .map(function (user) {\n\t       return user.first_name.toUpperCase();\n    });\n\ngs.info(value);\n```\n\nOutput:\n\n```\nOptional<ABEL>\n```\n\n## Optional - of\\(Any value\\)\n\nWraps a given value in an Optional object. For example, you can wrap the result of a GlideRecord query in an Optional object to use the associated methods.\n\n**Note:** This method is static. You do not need an instance of the class to use this method.\n\n|Name|Type|Description|\n|----|----|-----------|\n|value|Any|Value inside the Optional object.|\n\n|Type|Description|\n|----|-----------|\n|Optional|Object containing the passed-in value in the format `Optional<value>`.|\n\nThis example shows you how to generate an Optional object based on a GlideRecord query.\n\n```\nvar now_GR = new GlideRecord('task');\nnow_GR.addQuery('approval', 'not requested'); \nnow_GR.query();\nvar optional;\nif (now_GR.next()) {\noptional = Optional.of(now_GR.getUniqueValue());\n} else {\n    optional = Optional.empty(\"no results\");\n}\n\ngs.info(optional.get());\n```\n\nOutput:\n\n```\n00c269162d761010f87708b56757cbb3\n```\n\n## Optional - orElse\\(Any defaultValue\\)\n\nAdds a default value within the Optional object if the query does not return any results.\n\n|Name|Type|Description|\n|----|----|-----------|\n|defaultValue|Any|Value within the Optional object if the query does not return any results.|\n\n|Type|Description|\n|----|-----------|\n|Any|Value within the Optional object if the query does not return any results.|\n\nThis example shows how to return a value, even when the query is incorrect.\n\n```\nvar user = new global.GlideQuery('sys_user')\n    .get('1234', ['first_name', 'last_name'])\n    .orElse({ first_name: 'Default', last_name: 'User' });\n\ngs.info(JSON.stringify(user))\n```\n\nOutput:\n\n```\n{\n   \"first_name\":\"Default\",\n   \"last_name\":\"User\"\n}\n```\n\n"}}