diff --git a/content/en/docs/howto/extensibility/best-practices-javascript-actions.md b/content/en/docs/howto/extensibility/best-practices-javascript-actions.md index 64116e6f346..0bae9764b38 100644 --- a/content/en/docs/howto/extensibility/best-practices-javascript-actions.md +++ b/content/en/docs/howto/extensibility/best-practices-javascript-actions.md @@ -183,18 +183,17 @@ For information on how to use *Big.js*, consult the [big.js API](https://mikemcl Use the following code to create objects: ```javascript -mx.data.create({ - entity: "MyFirstModule.Cat", - callback: function(object) { - console.log("Object created on server"); - }, - error: function(error) { - console.error("Could not commit object:", error); - } -}); +import { create } from "mx-api/data" + +try { + const cat = await create({ entity: "MyFirstModule.Cat" }) + console.log("Object created on server:", cat); +} catch (err) { + console.error("Could not commit object:", err); +} ``` -For more information on creating objects, consult the [Create](https://apidocs.rnd.mendix.com/10/client/mx.data.html#.create) section of the *Mendix Client API*. +For more information on creating objects, consult the [Create](https://apidocs.rnd.mendix.com/11/client-mx-api/module-mx-api_data.html#.create) section of the *Mendix Client API*. #### Changing Objects @@ -290,36 +289,6 @@ Use the following code to employ an asynchronous return for when your nanoflow n Many APIs and functions are designed in an asynchronous way, and use callback functions or promises. A JavaScript action expects a promise to be returned. The promise should be resolved with the return value as expected in the action. -#### Understanding Promises - -A `Promise` object represents the eventual completion (or failure) of an asynchronous operation and its resulting value. - -Use the following code to wrap a callback API in a promise: - -```javascript -function AskConfirmation(question) { - // BEGIN USER CODE - return new Promise(function (resolve) { - mx.ui.confirmation({ - content: question, - handler: function() { - resolve(true); - }, - onCancel: function() { - resolve(false); - } - }); - }); - // END USER CODE -} -``` - -Explaining the callback code: - -* Use the standard Mendix Client to show a confirmation dialog box with an **OK** and a **Cancel** button (the execution of the nanoflow halts until the user clicks one of the buttons) -* The resolve will return a Boolean value, which is used as the return value of the action -* In the nanoflow, the return variable can be used for an alternative flow for confirmation and cancel - #### Understanding Promise API This function uses the Fetch API: diff --git a/content/en/docs/howto/extensibility/build-javascript-actions/write-javascript-github.md b/content/en/docs/howto/extensibility/build-javascript-actions/write-javascript-github.md index e3b03b14c9d..d250dea8696 100644 --- a/content/en/docs/howto/extensibility/build-javascript-actions/write-javascript-github.md +++ b/content/en/docs/howto/extensibility/build-javascript-actions/write-javascript-github.md @@ -91,7 +91,7 @@ To create a JavaScript action that can search for users on GitHub, follow the st const url = "https://api.github.com/search/users?q=" + query; const response = await fetch(url); // Fetch returns a promise, gets the url and wait for result const jsonData = await response.json(); // Transform to JSON - logger.debug("count results", jsonData.total_count); // log to the console a successful result + console.log("count results", jsonData.total_count); // log to the console a successful result return []; // return an empty list for now... // END USER CODE } @@ -104,6 +104,8 @@ To create a JavaScript action that can search for users on GitHub, follow the st 10. Finally, set a `Promise.all` return to wait for all promises to be resolved before the nanoflow can continue: ```javascript + import { create } from "mx-api/data" + export async function SearchGitHubUsers(query) { // BEGIN USER CODE if (!query) { @@ -112,24 +114,19 @@ To create a JavaScript action that can search for users on GitHub, follow the st const url = "https://api.github.com/search/users?q=" + query; const response = await fetch(url); const jsonData = await response.json(); - logger.debug("count", jsonData.total_count); + console.log("count", jsonData.total_count); const gitHubUsers = jsonData.items.map(createGitHubUser); return Promise.all(gitHubUsers); - function createGitHubUser(user) { - return new Promise(function (resolve, reject) { - mx.data.create({ - entity: "HowTo.GitHubUser", - callback: function(mxObject) { - mxObject.set("login", user.login); - mxObject.set("avatar_url", user.avatar_url); - resolve(mxObject); - }, - error: function(e) { - reject("Could not create object:" + error.message); - } - }); - }); + async function createGitHubUser(user) { + try { + const mxObject = await create({ entity: "HowTo.GitHubUser" }); + mxObject.set("login", user.login); + mxObject.set("avatar_url", user.avatar_url); + return mxObject; + } catch(err) { + throw new Error("Could not create object:" + err.message) + } } // END USER CODE } @@ -140,6 +137,8 @@ To create a JavaScript action that can search for users on GitHub, follow the st 11. The function will only set the `login` and `avatar_url` properties. To make it more flexible, you will make the function discover the available attributes and set them. Extend the domain model with more attributes from the API like so: ```javascript + import { create } from "mx-api/data" + export async function SearchGitHubUsers(query) { // BEGIN USER CODE if (!query) { @@ -148,30 +147,25 @@ To create a JavaScript action that can search for users on GitHub, follow the st const url = "https://api.github.com/search/users?q=" + query; const response = await fetch(url); const jsonData = await response.json(); - logger.debug("count", jsonData.total_count); + console.log("count", jsonData.total_count); const gitHubUsers = jsonData.items.map(createGitHubUser); return Promise.all(gitHubUsers); - function createGitHubUser(user) { - return new Promise(function (resolve, reject) { - mx.data.create({ - entity: "HowTo.GitHubUser", - callback: function(mxObject) { - // Dynamically set attributes - mxObject.getAttributes() - .forEach(function(attributeName) { - var attributeValue = user[attributeName]; - if (attributeValue) { - mxObject.set(attributeName, attributeValue); - } - }); - resolve(mxObject); - }, - error: function(error) { - reject("Could not create object:" + error.message); - } - }); - }); + async function createGitHubUser(user) { + try { + const mxObject = await create({ entity: "HowTo.GitHubUser" }); + // Dynamically set attributes + mxObject.getAttributes() + .forEach(attributeName => { + const attributeValue = user[attributeName]; + if (attributeValue) { + mxObject.set(attributeName, attributeValue); + } + }); + return mxObject; + } catch(err) { + throw new Error("Could not create object:" + err.message) + } } // END USER CODE } @@ -196,9 +190,11 @@ To create a JavaScript action that can search for users on GitHub, follow the st {{< figure src="/attachments/howto/extensibility/build-javascript-actions/write-javascript-github/select-user-entity.png" alt="select user entity" class="no-border" >}} -15. Your final step is updating the code. The new `userEntity` parameter has already been added. In the `mx.data.create` function, set `userEntity` as the `entity` to be created. Then, add some documentation for future reference: +15. Your final step is updating the code. The new `userEntity` parameter has already been added. In the `create` function, set `userEntity` as the `entity` to be created. Then, add some documentation for future reference: ```javascript + import { create } from "mx-api/data" + /* Searching users on GitHub.com, it could find users via various criteria. This action returns up to 100 results. @param {string} query - The query contains one or more search keywords and qualifiers. Qualifiers allow you to limit your search to specific areas of GitHub. @@ -225,31 +221,24 @@ To create a JavaScript action that can search for users on GitHub, follow the st const url = "https://api.github.com/search/users?q=" + query; const response = await fetch(url); const jsonData = await response.json(); - logger.debug("count", jsonData.total_count); const gitHubUsers = jsonData.items.map(createGitHubUser); return Promise.all(gitHubUsers); - function createGitHubUser(user) { - // Wrap the Mendix Client API in a promise - return new Promise(function (resolve, reject) { - mx.data.create({ - entity: userEntity, - callback: function(mxObject) { - // Dynamically set attributes - mxObject.getAttributes() - .forEach(function(attributeName) { - const attributeValue = user[attributeName]; - if (attributeValue) { - mxObject.set(attributeName, attributeValue); - } - }); - resolve(mxObject); - }, - error: function(error) { - reject("Could not create object:" + error.message); - } - }); - }); + async function createGitHubUser(user) { + try { + const mxObject = await create({ entity: userEntity }); + // Dynamically set attributes + mxObject.getAttributes() + .forEach(attributeName => { + const attributeValue = user[attributeName]; + if (attributeValue) { + mxObject.set(attributeName, attributeValue); + } + }); + return mxObject; + } catch(err) { + throw new Error("Could not create object:" + err.message) + } } // END USER CODE } diff --git a/content/en/docs/howto/security/best-practices-security.md b/content/en/docs/howto/security/best-practices-security.md index 362002cf942..209d779f9f5 100644 --- a/content/en/docs/howto/security/best-practices-security.md +++ b/content/en/docs/howto/security/best-practices-security.md @@ -139,7 +139,13 @@ This authentication option is not available for Published Web Services and can o If you choose this option, the API will expect a "X-Csrf-Token" HTTP request header to be set on each incoming request. This authentication option is particularly interesting for custom JavaScript and widget implementations. -The session token can be acquired by calling `mx.session.getConfig("csrftoken")` in JavaScript. This method call should be used before each API call to prevent cross-site request forgery (CSRF/XSRF). +The session token can be acquired by calling a Mendix Client API method to get the current CSRF token. This method should be called before each API call in your widget or JavaScript action to prevent cross-site request forgery (CSRF/XSRF). + +```javascript +import getCSRFToken from "mx-api/session"; + +const token = getCSRFToken(); +``` #### Authentication Option 3, Custom {#custom} diff --git a/content/en/docs/howto10/extensibility/best-practices-javascript-actions.md b/content/en/docs/howto10/extensibility/best-practices-javascript-actions.md index 4e75b149325..bf0a8e50161 100644 --- a/content/en/docs/howto10/extensibility/best-practices-javascript-actions.md +++ b/content/en/docs/howto10/extensibility/best-practices-javascript-actions.md @@ -183,18 +183,17 @@ For information on how to use *Big.js*, consult the [big.js API](https://mikemcl Use the following code to create objects: ```javascript -mx.data.create({ - entity: "MyFirstModule.Cat", - callback: function(object) { - console.log("Object created on server"); - }, - error: function(error) { - console.error("Could not commit object:", error); - } -}); +import { create } from "mx-api/data" + +try { + const cat = await create({ entity: "MyFirstModule.Cat" }) + console.log("Object created on server:", cat); +} catch (err) { + console.error("Could not commit object:", err); +} ``` -For more information on creating objects, consult the [Create](https://apidocs.rnd.mendix.com/10/client/mx.data.html#.create) section of the *Mendix Client API*. +For more information on creating objects, consult the [Create](https://apidocs.rnd.mendix.com/10/client-mx-api/module-mx-api_data.html#.create) section of the *Mendix Client API*. #### Changing Objects @@ -290,30 +289,6 @@ Use the following code to employ an asynchronous return for when your nanoflow n Many APIs and functions are designed in an asynchronous way, and use callback functions or promises. A JavaScript action expects a promise to be returned. The promise should be resolved with the return value as expected in the action. -#### Understanding Promises - -A `Promise` object represents the eventual completion (or failure) of an asynchronous operation and its resulting value. - -Use the following code to wrap a callback API in a promise: - -```javascript -function AskConfirmation(question) { - // BEGIN USER CODE - return new Promise(function (resolve) { - mx.ui.confirmation({ - content: question, - handler: function() { - resolve(true); - }, - onCancel: function() { - resolve(false); - } - }); - }); - // END USER CODE -} -``` - Explaining the callback code: * Use the standard Mendix Client to show a confirmation dialog box with an **OK** and a **Cancel** button (the execution of the nanoflow halts until the user clicks one of the buttons) diff --git a/content/en/docs/howto10/extensibility/build-javascript-actions/write-javascript-github.md b/content/en/docs/howto10/extensibility/build-javascript-actions/write-javascript-github.md index 6147a27d32f..039a5ce1bce 100644 --- a/content/en/docs/howto10/extensibility/build-javascript-actions/write-javascript-github.md +++ b/content/en/docs/howto10/extensibility/build-javascript-actions/write-javascript-github.md @@ -91,7 +91,7 @@ To create a JavaScript action that can search for users on GitHub, follow the st const url = "https://api.github.com/search/users?q=" + query; const response = await fetch(url); // Fetch returns a promise, gets the url and wait for result const jsonData = await response.json(); // Transform to JSON - logger.debug("count results", jsonData.total_count); // log to the console a successful result + console.log("count results", jsonData.total_count); // log to the console a successful result return []; // return an empty list for now... // END USER CODE } @@ -104,6 +104,8 @@ To create a JavaScript action that can search for users on GitHub, follow the st 10. Finally, set a `Promise.all` return to wait for all promises to be resolved before the nanoflow can continue: ```javascript + import { create } from "mx-api/data" + export async function SearchGitHubUsers(query) { // BEGIN USER CODE if (!query) { @@ -112,24 +114,19 @@ To create a JavaScript action that can search for users on GitHub, follow the st const url = "https://api.github.com/search/users?q=" + query; const response = await fetch(url); const jsonData = await response.json(); - logger.debug("count", jsonData.total_count); + console.log("count", jsonData.total_count); const gitHubUsers = jsonData.items.map(createGitHubUser); return Promise.all(gitHubUsers); - function createGitHubUser(user) { - return new Promise(function (resolve, reject) { - mx.data.create({ - entity: "HowTo.GitHubUser", - callback: function(mxObject) { - mxObject.set("login", user.login); - mxObject.set("avatar_url", user.avatar_url); - resolve(mxObject); - }, - error: function(e) { - reject("Could not create object:" + error.message); - } - }); - }); + async function createGitHubUser(user) { + try { + const mxObject = await create({ entity: "HowTo.GitHubUser" }); + mxObject.set("login", user.login); + mxObject.set("avatar_url", user.avatar_url); + return mxObject; + } catch(err) { + throw new Error("Could not create object:" + err.message) + } } // END USER CODE } @@ -139,7 +136,9 @@ To create a JavaScript action that can search for users on GitHub, follow the st 11. The function will only set the `login` and `avatar_url` properties. To make it more flexible, you will make the function discover the available attributes and set them. Extend the domain model with more attributes from the API like so: - ```javascript + ```javascript + import { create } from "mx-api/data" + export async function SearchGitHubUsers(query) { // BEGIN USER CODE if (!query) { @@ -148,30 +147,25 @@ To create a JavaScript action that can search for users on GitHub, follow the st const url = "https://api.github.com/search/users?q=" + query; const response = await fetch(url); const jsonData = await response.json(); - logger.debug("count", jsonData.total_count); + console.log("count", jsonData.total_count); const gitHubUsers = jsonData.items.map(createGitHubUser); return Promise.all(gitHubUsers); - function createGitHubUser(user) { - return new Promise(function (resolve, reject) { - mx.data.create({ - entity: "HowTo.GitHubUser", - callback: function(mxObject) { - // Dynamically set attributes - mxObject.getAttributes() - .forEach(function(attributeName) { - var attributeValue = user[attributeName]; - if (attributeValue) { - mxObject.set(attributeName, attributeValue); - } - }); - resolve(mxObject); - }, - error: function(error) { - reject("Could not create object:" + error.message); - } - }); - }); + async function createGitHubUser(user) { + try { + const mxObject = await create({ entity: "HowTo.GitHubUser" }); + // Dynamically set attributes + mxObject.getAttributes() + .forEach(function(attributeName) { + var attributeValue = user[attributeName]; + if (attributeValue) { + mxObject.set(attributeName, attributeValue); + } + }); + return mxObject; + } catch(err) { + throw new Error("Could not create object:" + err.message) + } } // END USER CODE } @@ -196,9 +190,11 @@ To create a JavaScript action that can search for users on GitHub, follow the st {{< figure src="/attachments/howto10/extensibility/build-javascript-actions/write-javascript-github/select-user-entity.png" alt="select user entity" class="no-border" >}} -15. Your final step is updating the code. The new `userEntity` parameter has already been added. In the `mx.data.create` function, set `userEntity` as the `entity` to be created. Then, add some documentation for future reference: +15. Your final step is updating the code. The new `userEntity` parameter has already been added. In the `create` function, set `userEntity` as the `entity` to be created. Then, add some documentation for future reference: ```javascript + import { create } from "mx-api/data" + /* Searching users on GitHub.com, it could find users via various criteria. This action returns up to 100 results. @param {string} query - The query contains one or more search keywords and qualifiers. Qualifiers allow you to limit your search to specific areas of GitHub. @@ -225,31 +221,24 @@ To create a JavaScript action that can search for users on GitHub, follow the st const url = "https://api.github.com/search/users?q=" + query; const response = await fetch(url); const jsonData = await response.json(); - logger.debug("count", jsonData.total_count); const gitHubUsers = jsonData.items.map(createGitHubUser); return Promise.all(gitHubUsers); - function createGitHubUser(user) { - // Wrap the Mendix Client API in a promise - return new Promise(function (resolve, reject) { - mx.data.create({ - entity: userEntity, - callback: function(mxObject) { - // Dynamically set attributes - mxObject.getAttributes() - .forEach(function(attributeName) { - const attributeValue = user[attributeName]; - if (attributeValue) { - mxObject.set(attributeName, attributeValue); - } - }); - resolve(mxObject); - }, - error: function(error) { - reject("Could not create object:" + error.message); - } - }); - }); + async function createGitHubUser(user) { + try { + const mxObject = await create({ entity: userEntity }); + // Dynamically set attributes + mxObject.getAttributes() + .forEach(function(attributeName) { + const attributeValue = user[attributeName]; + if (attributeValue) { + mxObject.set(attributeName, attributeValue); + } + }); + return mxObject; + } catch(err) { + throw new Error("Could not create object:" + err.message) + } } // END USER CODE } diff --git a/content/en/docs/howto10/security/best-practices-security.md b/content/en/docs/howto10/security/best-practices-security.md index d571863a071..935364c367c 100644 --- a/content/en/docs/howto10/security/best-practices-security.md +++ b/content/en/docs/howto10/security/best-practices-security.md @@ -139,7 +139,17 @@ This authentication option is not available for Published Web Services and can o If you choose this option, the API will expect a "X-Csrf-Token" HTTP request header to be set on each incoming request. This authentication option is particularly interesting for custom JavaScript and widget implementations. -The session token can be acquired by calling `mx.session.getConfig("csrftoken")` in JavaScript. This method call should be used before each API call to prevent cross-site request forgery (CSRF/XSRF). +The session token can be acquired by calling a Mendix Client API method to get the current CSRF token. This method should be called before each API call in your widget or JavaScript action to prevent cross-site request forgery (CSRF/XSRF). + +In Mendix versions below 10.23 you can call `mx.session.getConfig("csrftoken")` in your widget or JavaScript action. + +In Mendix versions 10.23 and above: + +```javascript +import getCSRFToken from "mx-api/session"; + +const token = getCSRFToken(); +``` #### Authentication Option 3, Custom {#custom} diff --git a/content/en/docs/refguide/modeling/integration/odata-services/published-odata-services/_index.md b/content/en/docs/refguide/modeling/integration/odata-services/published-odata-services/_index.md index f5ec2ec3cee..5e00180323f 100644 --- a/content/en/docs/refguide/modeling/integration/odata-services/published-odata-services/_index.md +++ b/content/en/docs/refguide/modeling/integration/odata-services/published-odata-services/_index.md @@ -182,12 +182,14 @@ This result is a header which looks like `Authorization: Basic QWxhZGRpbjpvcGVuI When you check this authentication method, the JavaScript in your app can access the REST service using the current user's session. -To prevent cross-site request forgery, the `X-Csrf-Token` header needs to be set on each request, for example: +To prevent cross-site request forgery, the `X-Csrf-Token` header needs to be set on each request. If you are using a JavaScript action, you can use an API to retrieve the token. ```js +import getCSRFToken from "mx-api/session"; + var xmlHttp = new XMLHttpRequest(); xmlHttp.open("GET", "http://mysite/odata/myservice/myentity", false); -xmlHttp.setRequestHeader("X-Csrf-Token", mx.session.getConfig("csrftoken")); +xmlHttp.setRequestHeader("X-Csrf-Token", getCSRFToken()); xmlHttp.send(null); ``` diff --git a/content/en/docs/refguide/modeling/integration/rest-services/published-rest-services/published-rest-service/_index.md b/content/en/docs/refguide/modeling/integration/rest-services/published-rest-services/published-rest-service/_index.md index 30724514f19..af024ca3aec 100644 --- a/content/en/docs/refguide/modeling/integration/rest-services/published-rest-services/published-rest-service/_index.md +++ b/content/en/docs/refguide/modeling/integration/rest-services/published-rest-services/published-rest-service/_index.md @@ -69,12 +69,14 @@ If authentication is required, you can select which authentication methods to su * Select **Active session** to allow access from JavaScript inside your current application * Once a user has logged into the browser, the JavaScript in your app can access the REST service using the current user's session * [Offline-first](/refguide/offline-first/) apps cannot use active session authentication, because they do not have sessions that stay active while the app is running -* To prevent cross-site request forgery, the `X-Csrf-Token` header needs to be set on each request, for example: +* To prevent cross-site request forgery, the `X-Csrf-Token` header needs to be set on each request; if you are using a JavaScript action, you can use an API to retrieve the token ```javascript + import getCSRFToken from "mx-api/session"; + var xmlHttp = new XMLHttpRequest(); xmlHttp.open("GET", "http://mysite/rest/myservice/myresource", false); - xmlHttp.setRequestHeader("X-Csrf-Token", mx.session.getConfig("csrftoken")); + xmlHttp.setRequestHeader("X-Csrf-Token", getCSRFToken()); xmlHttp.send(null); ``` diff --git a/content/en/docs/refguide/modeling/menus/translatable-texts/_index.md b/content/en/docs/refguide/modeling/menus/translatable-texts/_index.md index 556a97e8381..b1c38e6ecf9 100644 --- a/content/en/docs/refguide/modeling/menus/translatable-texts/_index.md +++ b/content/en/docs/refguide/modeling/menus/translatable-texts/_index.md @@ -88,7 +88,7 @@ There are two options to ensure that the language is changed: 1. Add the platform supported widget [HTML / JavaScript Snippet](https://marketplace.mendix.com/link/component/56/) to your app. 2. Create a pop-up page. 3. Place the HTMLSnippet widget on the pop-up page. - 4. Add the **JavaScript** content `mx.reloadWithState();` to the widget. + 4. Add the **JavaScript** content `window.reload();` to the widget. 5. Open your new pop-up page from a microflow when you want to switch the user's language. {{< figure src="/attachments/refguide/modeling/menus/translatable-texts/reload-with-state.png" alt="System Domain Model for User and Language" class="no-border" width="600" >}} diff --git a/content/en/docs/refguide10/modeling/integration/odata-services/published-odata-services/_index.md b/content/en/docs/refguide10/modeling/integration/odata-services/published-odata-services/_index.md index 203e766bac5..fecb4bd09f4 100644 --- a/content/en/docs/refguide10/modeling/integration/odata-services/published-odata-services/_index.md +++ b/content/en/docs/refguide10/modeling/integration/odata-services/published-odata-services/_index.md @@ -186,15 +186,28 @@ This result is a header which looks like `Authorization: Basic QWxhZGRpbjpvcGVuI When you check this authentication method, the JavaScript in your app can access the REST service using the current user's session. -To prevent cross-site request forgery, the `X-Csrf-Token` header needs to be set on each request, for example: +To prevent cross-site request forgery, the `X-Csrf-Token` header needs to be set on each request. If you are using a JavaScript action, you can use an API to retrieve the token. -```js +For Studio Pro versions 10.22 and below, see the example below: + +```javascript var xmlHttp = new XMLHttpRequest(); xmlHttp.open("GET", "http://mysite/odata/myservice/myentity", false); xmlHttp.setRequestHeader("X-Csrf-Token", mx.session.getConfig("csrftoken")); xmlHttp.send(null); ``` +For Studio Pro versions 10.23 and above, see the example below: + +```javascript +import getCSRFToken from "mx-api/session"; + +var xmlHttp = new XMLHttpRequest(); +xmlHttp.open("GET", "http://mysite/odata/myservice/myentity", false); +xmlHttp.setRequestHeader("X-Csrf-Token", getCSRFToken()); +xmlHttp.send(null); +``` + ##### Custom {#authentication-microflow} {{% alert color="info" %}} diff --git a/content/en/docs/refguide10/modeling/integration/rest-services/published-rest-services/published-rest-service/_index.md b/content/en/docs/refguide10/modeling/integration/rest-services/published-rest-services/published-rest-service/_index.md index 8efb9f8c387..bd4de90c43a 100644 --- a/content/en/docs/refguide10/modeling/integration/rest-services/published-rest-services/published-rest-service/_index.md +++ b/content/en/docs/refguide10/modeling/integration/rest-services/published-rest-services/published-rest-service/_index.md @@ -69,14 +69,27 @@ If authentication is required, you can select which authentication methods to su * Select **Active session** to allow access from JavaScript inside your current application * Once a user has logged into the browser, the JavaScript in your app can access the REST service using the current user's session * [Offline-first](/refguide10/offline-first/) apps cannot use active session authentication, because they do not have sessions that stay active while the app is running -* To prevent cross-site request forgery, the `X-Csrf-Token` header needs to be set on each request, for example: - - ```javascript - var xmlHttp = new XMLHttpRequest(); - xmlHttp.open("GET", "http://mysite/rest/myservice/myresource", false); - xmlHttp.setRequestHeader("X-Csrf-Token", mx.session.getConfig("csrftoken")); - xmlHttp.send(null); - ``` +* To prevent cross-site request forgery, the `X-Csrf-Token` header needs to be set on each request. If you are using a JavaScript action, you can use an API to retrieve the token. + +For Studio Pro versions 10.22 and below, see the following example: + +```javascript +var xmlHttp = new XMLHttpRequest(); +xmlHttp.open("GET", "http://mysite/rest/myservice/myresource", false); +xmlHttp.setRequestHeader("X-Csrf-Token", mx.session.getConfig("csrftoken")); +xmlHttp.send(null); +``` + +For Studio Pro versions 10.23 and above, see the following example: + +```javascript +import getCSRFToken from "mx-api/session"; + +var xmlHttp = new XMLHttpRequest(); +xmlHttp.open("GET", "http://mysite/rest/myservice/myresource", false); +xmlHttp.setRequestHeader("X-Csrf-Token", mx.session.getConfig("csrftoken")); +xmlHttp.send(null); +``` * Select **Custom** to authenticate using a microflow. This microflow is called every time a user wants to access a resource. diff --git a/content/en/docs/refguide10/modeling/menus/translatable-texts/_index.md b/content/en/docs/refguide10/modeling/menus/translatable-texts/_index.md index 864881ebcde..360c66c516a 100644 --- a/content/en/docs/refguide10/modeling/menus/translatable-texts/_index.md +++ b/content/en/docs/refguide10/modeling/menus/translatable-texts/_index.md @@ -88,7 +88,7 @@ There are two options to ensure that the language is changed: 1. Add the platform supported widget [HTML / JavaScript Snippet](https://marketplace.mendix.com/link/component/56/) to your app. 2. Create a pop-up page. 3. Place the HTMLSnippet widget on the pop-up page. - 4. Add the **JavaScript** content `mx.reloadWithState();` to the widget. + 4. Add the **JavaScript** content `window.reload();` to the widget. 5. Open your new pop-up page from a microflow when you want to switch the user's language. {{< figure src="/attachments/refguide10/modeling/menus/translatable-texts/reload-with-state.png" alt="System Domain Model for User and Language" class="no-border" width="600" >}}