Initial commit

Co-Authored-By: kotte <14197736+mrtamagotchi@users.noreply.github.com>
Co-Authored-By: mikaeltellhed <2311083+mikaeltellhed@users.noreply.github.com>
Co-Authored-By: Tore Knudsen <18231882+torekndsn@users.noreply.github.com>
Co-Authored-By: Michael Cartner <32543275+michaelcartner@users.noreply.github.com>
This commit is contained in:
Eric Tuvesson
2023-09-05 12:08:55 +02:00
commit 53f0d6320e
2704 changed files with 76354 additions and 0 deletions

View File

@@ -0,0 +1,40 @@
---
hide_title: true
hide_table_of_contents: true
title: Noodl.Arrays
---
# Noodl.Arrays
**Only available on the frontend**
The third part of the global data model in Noodl are arrays. Each array is reference by its **Id** using the `Noodl.Arrays`prefix, similar to objects and variables. You can learn more about arrays in the [arrays guide](/docs/guides/data/arrays). Changing an array will trigger an update of all **Array** node with the corresponding **Id**.
<div className="ndl-image-with-background xl">
![](/javascript/reference/arrays/arrays.png)
</div>
:::note
Generally arrays in Noodl are expected to contain objects. There is nothing stopping you putting other stuff in arrays but
:::
```javascript
// This will change the array with id MyArray and update all Arrays nodes
// with that id.
Noodl.Arrays.MyArray = [{ Hello: "There" }];
// Use this if you have spaces in your array id
Noodl.Arrays["Recepie List"] = [{ Name: "Fancy Burger" }];
// Reading arrays
console.log(Noodl.Arrays.MyArray);
// WARNING, you can access arrays like this but this will not trigger an update
// in Noodl. You should avoid modifying arrays like this.
Noodl.Arrays.MyArray.push({ Hello: "Again" });
// Instead, create a new array. This will trigger an update
// on all Array nodes with id MyArray
Noodl.Arrays.MyArray = Noodl.Arrays.MyArray.concat([{ Hello: "Again" }]);
```

View File

@@ -0,0 +1,19 @@
---
hide_title: true
hide_table_of_contents: true
title: Noodl.CloudFunctions
---
# Noodl.CloudFunctions
**Only available on the frontend**
The **Noodl.CloudFunctions** service lets you call Noodl cloud functions.
#### **`Noodl.CloudFunctions.run(functionName,parameters)`**
This function will call a cloud function in the backend.
```javascript
const result = await Noodl.CloudFunctions.run("myFunctionName", {
SomeParamater: "yes",
});
```

View File

@@ -0,0 +1,46 @@
---
hide_title: true
hide_table_of_contents: true
title: Component
---
# Component
**Only available on the frontend**
The `Component` object is ony available in [Function](/nodes/javascript/function) and [Script](/nodes/javascript/script) nodes and it contains things related to the component scope where the **Function** or **Script** node is executing.
`Component.Object` is the [Component Object](/nodes/component-utilities/component-object) of the current component and you can use it just like any other [Noodl.Object](/javascript/reference/object). Most commonly this means accessing the properties of the object. When you set a property any **Component Object** node in this component instance will update accordingly.
<div className="ndl-image-with-background xl">
![](/javascript/reference/component/component-object.png)
</div>
In the example above the **Function** node called _Update selection_ is modifying the **Component Object** to create a new array for **Selection**. This is done by accessing the **Checkboxes** array in the component object and filtering and mapping that array.
```javascript
Component.Object.Selection = Component.Object.Checkboxes.filter(
(o) => o.Checked
).map((o) => ({ Value: o.Value }));
```
`Component.ParentObject` is similair but this object is the [Parent Component Object](/nodes/component-utilities/parent-component-object), that is the **Component Object** of the parent component in the visual heirarchy. It is also used like any other [Noodl.Object](/javascript/reference/object).
`Component.RepeaterObject` If this component is the template of a repeater this will contain the object of the items array corresponding to this specific component instance. That is the same object as if you set an object **Id Source** to **From Repeater**, as shown below.
<div className="ndl-image-with-background l">
![](/javascript/reference/component/from-repeater-props.png)
</div>
Below is an example of such an object in a component.
<div className="ndl-image-with-background l">
![](/javascript/reference/component/repeater-object.png)
</div>
If this component is not directly the template used by a repeater but instead a sub component, you can still access the object. The object will be resolved by following the instance parent chain of components until it reaches a component that is a repeater template instance.

View File

@@ -0,0 +1,76 @@
---
hide_title: true
hide_table_of_contents: true
title: Noodl.Events
---
# Noodl.Events
**Only available on the frontend**
This is the Noodl event emitter, you can use it to receive and send events from your scripts. You can learn more about events in the [guide](/docs/guides/business-logic/events).
<div className="ndl-image-with-background xl">
![](/javascript/reference/events/events.gif)
</div>
#### **`Noodl.Events.emit(eventName, data)`**
Send an event. Works well together with _Event Receivers_.
```javascript
Noodl.Events.emit("event name", {
value: "hello",
someOtherValue: 100,
});
```
#### **`Noodl.Events.on(eventName, callback(data))`**
#### **`Noodl.Events.once(eventName, callback(data))`**
Receive an event. Works together with _Event Senders_
```javascript
Noodl.Events.on("event name", function (eventData) {
console.log(eventData.value);
});
```
#### **`Noodl.Events.off(eventName, callback(data))`**
Remove an event handler.
```javascript
function onEventName(eventData) {
console.log(eventData.value);
}
Noodl.Events.on("event name", onEventName);
Noodl.Events.off("event name", onEventName);
```
## Features
### Listen to Page Router navigation
Here is an example of how you can listen to the Page Router navigation events.
```js
Script.Outputs = {
Navigated: "signal",
};
function onNavigated({ routerName, path, title, component }) {
Script.Outputs.Navigated();
}
Script.Signals.DidMount = function () {
Noodl.Events.on("NoodlApp_Navigated", onNavigated);
};
Script.OnDestroy = function () {
Noodl.Events.off("NoodlApp_Navigated", onNavigated);
};
```

View File

@@ -0,0 +1,39 @@
---
hide_title: true
hide_table_of_contents: true
title: Noodl.Files
---
# Noodl.Files
The **Noodl.Files** service lets you access the cloud services files.
#### **`Noodl.Files.upload(file,options)`**
**Only available on the frontend**
This function will upload a file to the backend. You can specify a progress callback using the options.
<div className="ndl-image-with-background xl">
![](/javascript/reference/files/upload.png)
</div>
```javascript
const cloudFile = await Noodl.Files.upload(Inputs.File, {
onProgress: (p) => {
console.log(p.total, p.loaded);
},
});
console.log(cloudFile.name);
console.log(cloudFile.url);
```
#### **`Noodl.Files.delete(fileName)`**
**Only available in cloud functions**
This function will delete a file that has been uploaded to the backend. You need to provide the file name that was returned when the file was uploaded. So not the full `url` but the `hash+filename` returned by the upload function.
```javascript
// Can only be done in cloud functions
await Noodl.Files.delete(filename);
```

View File

@@ -0,0 +1,44 @@
---
hide_title: true
hide_table_of_contents: true
title: Noodl.Navigation
---
# Noodl.Navigation
**Only available on the frontend**
The **Noodl.Navigation** service lets you perform navigation from functions and scripts.
#### **`Noodl.Navigation.showPopup(componentPath,parameters)`**
This function will show the provided visual component as a popup.
```javascript
const result = await Noodl.Navigation.showPopup("#mysheet/mypopupcomponent", {
Message: "hello",
});
console.log(result.action); // The action used to close the popup
console.log(result.parameters); // The close parameters
```
The **parameters** are provided to the component as inputs, and must match the component input names.
#### **`Noodl.Navigation.navigate(routerName,targetPageName,parameters)`**
This function will navigate on a given page router, identified with **routerName**, to a provided page, identified with **targetPageName** (the path to the page component), and give it the parameters provided in **parameters**.
```javascript
Noodl.Navigation.navigate("Main", "#mysheet/DetailsPage", {
ObjectId: theClickedObjectId,
});
```
#### **`Noodl.Navigation.navigateToPath(path,query)`**
This function will navigate to a specific url path. You can provide query parameters as an object. The function will use the current path mode selected in the project, hash or path.
```javascript
Noodl.Navigation.navigateToPath("/main/details/" + theClickedObjectId, {
query: {
filter: true,
},
});
```

View File

@@ -0,0 +1,147 @@
---
hide_title: true
hide_table_of_contents: true
title: Noodl.Object
---
# Noodl.Object
Allows access to [Object](/nodes/data/object/object-node) from Javascript. You can learn more about objects and how you use them in your Noodl applications [here](/docs/guides/data/objects).
#### **`Noodl.Object.get(id)`**
Returns the object with the specified id. This function will return a new empty object if the id is
not previously used. If you want to check if an object exists use the `Noodl.Object.exists` function.
This is the same as accessing the object through `Noodl.Objects`.
#### **`Noodl.Object.create(data)`**
This function will create a new object and return it.
The properties of the object will be that of the supplied data. A special case is
the id attribute that will become the id of the object and not part of the object properties.
E.g. the code below will create an object with two properties and the id set to 'A'.
```javascript
Noodl.Object.create({
id: "A",
myProp1: 10,
myProp2: "Hello",
myProp3: Noodl.Object.create({ anotherProp: 15 }),
});
```
If no id is provided the newly created object will get a unique id assigned.
As illustrated in the example above object properties can contain references to other objects.
#### **`Noodl.Object.exists(id)`**
Returns true if an object with the specified Id has been created with a call to Noodl.Object.get or Noodl.Object.create.
#### **`object.on(event,listener)`**
#### **`object.off(event,listener)`**
Add and remove an event listener from the object.
Supported events:
- `change` - any property of the object is changed
- `add` - the object is added to a array
- `remove` - the object is removed from a array.
Example usage:
```javascript
myObject.on("change", function (args) {
// property with name args.name was changed
// new value in args.value
// old value in args.old
});
myObject.on("add", function (args) {
// object was added to the array args.array
});
myObject.on("remove", function (args) {
// object was removed from the array args.array
});
```
#### **`object.getId()`**
Returns the Id of the object.
#### **`object.set(name,value,options)`**
Sets a property of the object. The name and value of the property should be provided to the function.
`myObject.set('myProp1',44)`
This is equal to just setting the property of the object directly:
`myObject.myProp1 = 44`
Optionally, dot notation can be used to set a sub property.
If a property of the object is another object, then you can set a property of the object
e.g. `myProp3.anotherProp`. To enable this you must supply the options `{resolve:true}`.
`myObject.set('myProp3.anotherProp',50,{resolve:true})`
#### **`object.setAll(data)`**
This function performs a set on all properties of the specified object.
This is equal to calling set for all properties of the data object.
Updating the `id` property is not supported, and will be ignored.
```js
// Create a Noodl object
Noodl.Object.create({
id: "unique",
valueA: 1,
valueB: 2,
});
// This object, Noodl.Objects["unique"]
// will now contain {valueA: 1, valueB: 2}
// When calling setAll
Noodl.Objects["unique"].setAll({
valueA: 3,
});
// The object will now be:
// {valueA: 3, valueB: 2}
```
#### **`object.fill(value)`**
This function sets all the current properties to the new value, except of the id.
```js
// Create a Noodl object
Noodl.Object.create({
id: "unique",
valueA: 1,
valueB: 2,
});
// This object, Noodl.Objects["unique"]
// will now contain {valueA: 1, valueB: 2}
// When calling setAll
Noodl.Objects["unique"].fill(5);
// The object will now be:
// {valueA: 5, valueB: 5}
```
#### **`object.get(name,options)`**
Returns the value of the property with the specified name.
As in the set function the dot notation can be used if the object has another object as a property,
if the options {resolve:true} is supplied.
`myObject.get('myProp3.anotherProp',{resolve:true})`
This is equal to reading the property directly:
`myObject.myProp3.anotherProp`

View File

@@ -0,0 +1,41 @@
---
hide_title: true
hide_table_of_contents: true
title: Noodl.Objects
---
# Noodl.Objects
One step above **Variable**s are **Object**s,
this is a global data model of Noodl objects.
Each object is referenced with an **Id** and can contain a set of properties.
You can access alla objects in your workspace through their **Id** and the `Noodl.Objects` prefix.
Change a property of an object will trigger all connections from object nodes with the corresponding **Id** and property.
You can learn more about objects and how you use them in your Noodl applications [here](/docs/guides/data/objects).
<div className="ndl-image-with-background xl">
![](/javascript/reference/objects/objects.png)
</div>
```javascript
// This will change the property MyProperty
// of object with id MyObjectId and trigger
// all object nodes (with that id) in your project
Noodl.Objects.MyObjectId.MyProperty = "Hello";
// Use this notation of that object id contains spaces
Noodl.Objects["Form Values"].input_text = "Whoops";
Noodl.Objects["Form Values"]["A property with spaces"] = 20;
// Reading an object property
console.log(Noodl.Objects.CurrentUser.Name);
// This will set all properties of the object you assign with
// to the object with id "SomeId"
// You cannot set the id property this way,
// that property will be ignored if part of the object you assign
Noodl.Objects.SomeId = { ... }
```

View File

@@ -0,0 +1,15 @@
---
hide_title: true
hide_table_of_contents: true
title: Reference Documentation
---
# Reference Documentation
Here you will find the reference documentation for the Noodl Javascript API that you can use in [Function](/nodes/javascript/function) and [Script](/nodes/javascript/script) nodes but also in other nodes such as the [REST](/nodes/data/rest) node, or when creating your own modules and code Noodl nodes.
You can always reach the API using the `Noodl.` prefix, such as:
```javascript
Noodl.Variables.MyVariable = 10;
```

View File

@@ -0,0 +1,313 @@
---
hide_title: true
hide_table_of_contents: true
title: Noodl.Records
---
# Noodl.Records
With **Records** you can query, read and write records to the cloud database. All functions are **async** and will throw an exception if they fail.
```javascript
try {
await Noodl.Records.delete(myRecord);
} catch (e) {
console.log(e);
}
```
#### **`Noodl.Records.query(className,query,options)`**
This is an **async** function that will query the database using the query that you provide and return the result or throw an exception if failed. The **query** parameter has the same format as the [advanced query](/nodes/data/cloud-data/query-records#advanced-filters) of the **Query Records** node.
```javascript
const results = await Noodl.Records.query("myClass", {
Completed: { equalTo: true },
});
```
The result is an array of **Noodl.Object**. The **options** can be used to specify sorting, it also follows the same pattern as the advanced filters of the **Query Records** node.
```javascript
const results = await Noodl.Records.query(
"myClass",
{
Completed: { equalTo: true },
},
{
sort: ["createdAt"],
}
);
```
You can also specify the limit for how many records to return as a maximum (defaults to 100) with the **limit** option, and if you want the returned records to start from a given index specify the **skip** option.
```javascript
const results = await Noodl.Records.query(
"myClass",
{
Completed: { equalTo: true },
},
{
sort: ["-createdAt"], // use - to sort descending
skip: 50,
limit: 200,
}
);
```
If you are limiting your results or if you have more records that the maximum allowed returned count then you might want to know the total record count to enable pagination. You can do this with the **count** option. Note that this changes the returned value to an object with **results** and **count**.
```javascript
const res = await Noodl.Records.query(
"myClass",
{
Completed: { equalTo: true },
},
{
sort: ["-createdAt"], // use - to sort descending
skip: 50,
limit: 200,
count:true,
}
);
console.log(res.results); // This is the array with results
console.log(res.count); // This is the total count that matches the query
```
If you have properties in the returned records that are pointers they will by default returned as a string containing the **Id** of the record that they are pointing to (if any). You can hovever choose to include the entire record by using the `include` option. In the example below immagine that we have a property that is a pointer called **Customer** that points to a customer record. By using the `include` options as shown below the returned records will now include the entire object and all properties instead of just the pointer value.
```javascript
const results = await Noodl.Records.query(
"myClass",
{},
{
include: "Customer",
}
);
```
You can also use dot notation to recursively include points wihtin included objects. In the example below we also include records pointed to by the `Author` property and within those objects also any records pointed to by the `Location` property.
```javascript
const results = await Noodl.Records.query(
"myClass",
{},
{
include: "Customer,Author.Location",
}
);
```
By default all properties are returned for all records in the result. This is sometimes not the preferred way since it can result in big responses if you are only looking for a few properties. You can use the `select` option to specify the names of the properties you want included in the result. The below example will only return the `Title`and `Body` properties in the result.
```javascript
const results = await Noodl.Records.query(
"myClass",
{
Completed: { equalTo: true },
},
{
select: "Title,Body",
}
);
```
:::note
One important note, even though only a select few properties are returned from the cloud service they are merged with any existing properties in the record data model that have previously been fetched. Since all record objects are global to the Noodl application.
:::
#### **`Noodl.Records.count(className,query)`**
This function returns the count of the number of records of a given class, optionally matching a query filter.
```javascript
// The number of records of myClass in the database
const count = await Noodl.Records.count("myClass");
// The number of myClass records in the database that match a query
const completedCount = await Noodl.Records.count("myClass", {
Completed: { equalTo: true },
});
```
#### **`Noodl.Records.distinct(className,property,query)`**
**Only available in cloud functions**
This function returns an array of unique values for a given propery or all records in the database of a given class. Optionally you can suppoly a query filter.
```javascript
// The unique values of the "category" property of all records of myClass in the database.
const categories = await Noodl.Records.distinct("myClass", "category");
// The unique values of the "category" property of all records of myClass in the database that matches the query, e.g. that have the property Completed set to true.
const completedCount = await Noodl.Records.distinct("myClass", "category", {
Completed: { equalTo: true },
});
```
#### **`Noodl.Records.fetch(objectOrId,options)`**
Use this function to fetch the latest properties of a specific record from the cloud database. It will return the object / record.
```javascript
// If you use the a record ID you must also specify the class
const myRecord = await Noodl.Records.fetch(myRecordId, {
className: "myClass",
});
// You can also fetch a record you have previously fetched or received from a
// query, to get the latest properties from the backend
await Noodl.Records.fetch(myRecord);
```
By default fetch will return pointer properties as the string **Id** of the object pointed to. But you can use the `include` option to specify that you want the content of the object to be returned instead.
```javascript
// By using include the request will return the pointed to object with all properties instead of
// just the string Id
await Noodl.Records.fetch(myRecord,{
include:["Customer","Author"]
});
```
#### **`Noodl.Records.save(objectOrId,properties,options)`**
Use this function to write an existing record to the cloud database. It will attempt to save all properties of the record / object if you don't specify the optional properties argument, if so it will set and save those properties.
```javascript
Noodl.Objects[myRecordId].SomeProperty = "hello";
// If you use the record id to save, you need to specify the classname explicitly
// by specfiying null or undefinded for properties it will save all proporties in
// the record
await Noodl.Records.save(myRecordId, null, { className: "myClass" });
// Or use the object directly
await Noodl.Records.save(Noodl.Objects[myRecordId]);
// Set specified properties and save only those to the backned
await Noodl.Records.save(myRecord, {
SomeProperty: "hello",
});
```
#### **`Noodl.Records.increment(objectOrId,properties,options)`**
This function will increment (or decrease) propertis of a certain record saving it to the cloud database in a race condition safe way. That is, normally you would have to first read the current value, modify it and save it to the database. Here you can do it with one operation.
```javascript
// Modify the specified numbers in the cloud
await Noodl.Records.increment(myRecord, {
Score: 10,
Life: -1,
});
// Like save, you can use a record Id and class
await Noodl.Records.save(myRecordId, { Likes: 1 }, { className: "myClass" });
```
Using the options you can also specify access control as described in this [guide](/docs/guides/cloud-data/access-control), this let's you control which users can access a specific record. The access control is specified as below:
```javascript
await Noodl.Records.save(myRecord, null, {
acl: {
"*": { read: true, write: false }, // "*" means everyone, this rules gives everyone read access but not write
"a-user-id": { read: true, write: true }, // give a specific user write access
"role:a-role-name": { read: true, write: true }, // give a specific role write access
},
});
```
#### **`Noodl.Records.create(className,properties,options)`**
This function will create a new record in the cloud database and return the **Noodl.Object** of the newly created record. If it's unsuccessful it will throw an exception.
```javascript
const myNewRecord = await Noodl.Records.create("myClass", {
SomeProperty: "Hello",
});
console.log(myNewRecord.SomeProperty);
```
You can use the **options** agrument to specify access control rules as detailed under **Noodl.Records.save** above.
#### **`Noodl.Records.delete(objectOrId,options)`**
Use this function to delete an existing record from the cloud database.
```javascript
// If you specify the id of a record to be deleted, you must also provide the
// class name in the options
await Noodl.Records.delete(myRecordId, { className: "myClass" });
// Or use the object directly (provided it was previously fetched or received via a query)
await Noodl.Records.delete(Noodl.Objects[myRecordId]);
```
#### **`Noodl.Records.addRelation(options)`**
Use this function to add a relation between two records.
```javascript
// You can either specify the Ids and classes directly
await Noodl.Records.addRelation({
className: "myClass",
recordId: "owning-record-id",
key: "the-relation-key-on-the-owning-record",
targetRecordId: "the-id-of-the-record-to-add-a-relation-to",
targetClassName: "the-class-of-the-target-record",
});
// Or if you already have two records that have been previously fetched or returned from a
// query
await Noodl.Records.addRelation({
record: myRecord,
key: "relation-key",
targetRecord: theTargetRecord,
});
```
#### **`Noodl.Records.removeRelation(options)`**
Use this function to remove a relation between two records.
```javascript
// You can either specify the Ids and classes directly
await Noodl.Records.removeRelation({
className: "myClass",
recordId: "owning-record-id",
key: "the-relation-key-on-the-owning-record",
targetRecordId: "the-id-of-the-record-to-remove-a-relation-to",
targetClassName: "the-class-of-the-target-record",
});
// Or if you already have two records that have been previously fetched or returned from a
// query
await Noodl.Records.removeRelation({
record: myRecord,
key: "relation-key",
targetRecord: theTargetRecord,
});
```
#### **`Noodl.Records.aggregate(className,aggregates,query)`**
**Only available in cloud functions**
This function will compute a set of aggregates based on properties in the records. It can be limited with a query. You can use the following aggregate functions:
- `sum` Compute the sum of a number property access matching records.
- `min` Compute the minimum value of a number property access matching records.
- `max` Compute the maximum value of a number property access matching records.
- `avg` Compute the average value of a number property access matching records.
```javascript
// This will compute two averages on all records of myClass, TotalCost will be the sum of all Cost properties, and AverageSalary will be the average of all Salary properties
const categories = await Noodl.Records.aggregate("myClass", {
TotalCost: { sum: "Cost" },
AverageSalary: { avg: "Salary" },
});
// This will compute and return the maximum and minimum age for records with Category equal to Remote
const completedCount = await Noodl.Records.aggregate(
"myClass",
{
MinAge: { min: "Age" },
MaxAge: { max: "Age" },
},
{
Category: { equalTo: "Remote" },
}
);
```

View File

@@ -0,0 +1,155 @@
---
hide_title: true
hide_table_of_contents: true
title: Noodl.Users
---
# Noodl.Users
The **Noodl.Users** object let's you access the current session user.
#### **`Noodl.Users.logIn(options)`**
This function will attempt to login to create a user session. After a successful login you can access the user object with `Noodl.Users.Current`
```javascript
// On the frontend you log in and access the user via Noodl.Users.Current
await Noodl.Users.logIn({
username: "my-username",
password: "my-password",
});
console.log(Noodl.Users.Current.UserId);
// When running in a cloud function it also returns the user object
const user = await Noodl.Users.logIn({
username: "my-username",
password: "my-password",
});
console.log(user.sessionToken);
```
#### **`Noodl.Users.signUp(options)`**
**Only available on the frontend**
This function will attempt to sign up a new user, and if successful that user will become the current user session. Username, email and password are required options and properties is optional.
```javascript
await Noodl.Users.signUp({
username: "my-username",
email: "my-email",
password: "my-password",
properties: {
SomeProperty: true,
},
});
```
#### **`Noodl.Users.become(sessionToken)`**
**Only available on the frontend**
This function will attempt to login a user with an existing session token. Session tokens can be created in cloud functions e.g. using the `impersonate` function. After a successful login you can access the user object with `Noodl.Users.Current`
```javascript
// Call this from a function node with Inputs.SessionToken
try {
await Noodl.Users.become(Inputs.SessionToken);
} catch (e) {
Outputs.Failure();
throw e;
}
// You can now access the user
const userId = Noodl.Users.Current.UserId;
Outputs.Success();
```
#### **`Noodl.Users.impersonate(username,options)`**
**Only available in cloud functions**
With this function you can get a session token for a user that you can later send to the client to log that user in. This does not require a password and must be run on a cloud function (since they all have full access to the database). You can provide a duration for the session, or it will expire after 24 hours as default. If successful this call will return a user object that contains a session token that you can return to the client and use with the `become` function.
**installationId** is an optional that is a unique id for the client if you don't want to share sessions between different clients. Most common is to generate a random id on the client and pass to the cloud function when you are logging in.
```javascript
try {
const user = await Noodl.Users.impersonate("test@email.com", {
duration: 1 * 60 * 60 * 1000, // have the session last 1 hour
installationID: "xyz",
});
Outputs.SessionToken = user.sessionToken;
Outputs.Success();
} catch (e) {
Outputs.Failure();
throw e;
}
```
#### **`Noodl.Users.Current`**
This function will return the current user object and properties if one exists.
```javascript
const user = Noodl.Users.Current;
if (user) {
// A user is logged in
console.log(user.UserId); // the user id of the current user
console.log(user.Properties.SomeProperty);
} else {
// No user session
}
```
#### **`Noodl.Users.Current.fetch()`**
This function will fetch that laters properties of the user object from the cloud database. It will throw an exception if the user session has expired.
```javascript
await Noodl.Users.Current.fetch();
```
#### **`Noodl.Users.Current.save()`**
This function will attempt to save the properties of the current user. If you have made changes to the **current()** user object you will need to call this function to write the changes to the backend.
If the `password` has been updated it will terminate all the sessions so the user has to login again.
```javascript
await Noodl.Users.Current.save();
```
#### **`Noodl.Users.Current.logOut()`**
**Only available on the frontend**
This function will log out the current user and terminate the session.
```javascript
await Noodl.Users.Current.logOut();
```
#### **`Noodl.Users.on(eventName,callback)`**
**Only available on the frontend**
You can use this function to listen for events related to the user service.
```javascript
Noodl.Users.on("sessionLost", () => {
// This is called when the session has expired
});
Noodl.Users.on("loggedIn", () => {
// This is called when a user has successfully logged in
});
Noodl.Users.on("loggedOut", () => {
// This is called when a user has successfully logged out
});
```
#### **`Noodl.Users.off(eventName,callback)`**
**Only available on the frontend**
You use this function to remove an event listener from a specific event.

View File

@@ -0,0 +1,29 @@
---
hide_title: true
hide_table_of_contents: true
title: Noodl.Variables
---
# Noodl.Variables
Variables are the simplest form of global data model in Noodl. You can learn more about variables in the [guide](/docs/guides/data/variables). You can access all variables in your application trough the `Noodl.Variables` object. Changing a variable will trigger all connections to be updated for all **Variable** nodes in your project with the corresponding variable name.
<div className="ndl-image-with-background xl">
![](/javascript/reference/variables/variables.png)
</div>
```javascript
// This will change the variable named MyVariable
// and trigger all variable nodes in your project
Noodl.Variables.MyVariable = "Hello";
// Use this if you have spaces in your variable name
Noodl.Variables["My Variable"] = 10;
Noodl.Variables.userName = "Mickeeeey";
// Reading variables
console.log(Noodl.Variables.userName);
```