mirror of
https://github.com/noodlapp/noodl-docs.git
synced 2026-01-11 23:02:54 +01:00
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:
40
javascript/reference/arrays.md
Normal file
40
javascript/reference/arrays.md
Normal 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">
|
||||
|
||||

|
||||
|
||||
</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" }]);
|
||||
```
|
||||
19
javascript/reference/cloudfunctions.md
Normal file
19
javascript/reference/cloudfunctions.md
Normal 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",
|
||||
});
|
||||
```
|
||||
46
javascript/reference/component.md
Normal file
46
javascript/reference/component.md
Normal 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">
|
||||
|
||||

|
||||
|
||||
</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">
|
||||
|
||||

|
||||
|
||||
</div>
|
||||
|
||||
Below is an example of such an object in a component.
|
||||
|
||||
<div className="ndl-image-with-background l">
|
||||
|
||||

|
||||
|
||||
</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.
|
||||
76
javascript/reference/events.md
Normal file
76
javascript/reference/events.md
Normal 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">
|
||||
|
||||

|
||||
|
||||
</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);
|
||||
};
|
||||
```
|
||||
39
javascript/reference/files.md
Normal file
39
javascript/reference/files.md
Normal 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">
|
||||
|
||||

|
||||
|
||||
</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);
|
||||
```
|
||||
44
javascript/reference/navigation.md
Normal file
44
javascript/reference/navigation.md
Normal 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,
|
||||
},
|
||||
});
|
||||
```
|
||||
147
javascript/reference/object.md
Normal file
147
javascript/reference/object.md
Normal 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`
|
||||
41
javascript/reference/objects.md
Normal file
41
javascript/reference/objects.md
Normal 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">
|
||||
|
||||

|
||||
|
||||
</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 = { ... }
|
||||
```
|
||||
15
javascript/reference/overview.md
Normal file
15
javascript/reference/overview.md
Normal 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;
|
||||
```
|
||||
313
javascript/reference/records.md
Normal file
313
javascript/reference/records.md
Normal 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" },
|
||||
}
|
||||
);
|
||||
```
|
||||
155
javascript/reference/users.md
Normal file
155
javascript/reference/users.md
Normal 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.
|
||||
29
javascript/reference/variables.md
Normal file
29
javascript/reference/variables.md
Normal 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">
|
||||
|
||||

|
||||
|
||||
</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);
|
||||
```
|
||||
Reference in New Issue
Block a user