2

Upload file with Ninox API REST

 

I’ve been trying to upload files via the Ninox API for quite some time. With the invaluable help of Ninox’s technical support, I’ve finally managed to get it working. Since I’ve noticed several discussions on this topic without a definitive answer, I thought it would be helpful to share the solution I’ve found.

 

The first solution relies entirely on Ninox scripting, allowing you to upload files directly from Ninox to Ninox :

"Function to upload a file to Ninox. This function takes the base64 encoded file data, file name, API key, and other necessary identifiers to upload the file to the specified Ninox database record.";
function uploadFileToNinox(base64Data : text,fileName : text,APIKey : text,teamId : text,databaseId : text,tableId : text,recordId : number,fieldId : text) do
    "Initialize a variable to store the HTTP request result.";
    let res := {};
    "Construct the API URL for file upload.";
    let apiUrl := "https://api.ninoxdb.de/v1/teams/" + teamId + "/databases/" + databaseId +
        "/tables/" +
        tableId +
        "/records/" +
        recordId +
        "/files";
    "Define the headers for the HTTP request, including authorization via the API token.";
    let headers := {
            Authorization: "Bearer " + APIKey,
            'Content-Type': "multipart/form-data"
        };
    "Prepare the file to be sent as an array containing the file name and base64 content.";
    let fileArray := [{
                name: fileName,
                value: base64Data
            }];
    "Initialize the body of the request. Add the fieldId if it is provided.";
    let body := {};
    if fieldId then
        setItem(body, "fieldId", fieldId)
    end;
    "Execute the HTTP POST request to upload the file.";
    let response := http("POST", apiUrl, headers, body, fileArray);
    "Handle the response: if an error is returned, store it in res. Otherwise, provide a success message.";
    if response.error then
        res := {
                error: response.error
            }
    else
        res := {
                result: "The file " + fileName + " has been successfully uploaded.",
                data: response.result
            }
    end;
    "Return the result of the upload operation.";
    res
end;

"Load the file in base64 from the local file system.";
var base64Content := loadFileAsBase64URL(File);

"Define the file name and API key variables.";
var fileName := "Uploaded." + last(split(text(File), "."));
var apiKey := first(select Config).'API Key';

"Call the function to upload the file to Ninox with the required parameters.";
var response := uploadFileToNinox(base64Content, fileName, apiKey, teamId(), databaseId(), tableId(this), number(this.Id), "F2");

"Display the result of the upload in the debug console and via an alert to the user.";
debug("Upload");
alert("Upload result : " + text(response))

 

 

 

The second solution is written in JavaScript and enables file uploads from any other platform.

function uploadFileToNinox(base64Data, fileName, APIKey, teamId, databaseId, tableId, recordId, fieldId = null) {
  // Reconstitute the URL based on the provided template
  const url = `https://api.ninoxdb.de/v1/teams/${teamId}/databases/${databaseId}/tables/${tableId}/records/${recordId}/files`;

  // Convert the Base64 string into a Blob object
  const binaryString = atob(base64Data); // Decode the Base64 encoded string into a binary string
  const binaryLen = binaryString.length; // Get the length of the binary string
  const bytes = new Uint8Array(binaryLen); // Create a Uint8Array to hold the binary data
  for (let i = 0; i < binaryLen; i++) {
    bytes[i] = binaryString.charCodeAt(i); // Convert each character in the binary string to a byte and store it in the Uint8Array
  }
  const fileBlob = new Blob([bytes], { type: "text/plain" }); // Create a Blob object from the bytes array with the specified MIME type

  // Create a FormData object and append the file
  const formData = new FormData();
  formData.append("file", fileBlob, fileName); // Append the Blob object (file) to the FormData under the key "file"

  if (fieldId) {
    formData.append("fieldId", fieldId); // Optionally append a fieldId to the FormData if it's provided
  }

  // Send the request with fetch
  fetch(url, {
    method: "POST", // Use the POST method to send the data
    headers: {
      "Authorization": "Bearer " + APIKey // Add the Authorization header with the Bearer token
      // 'Content-Type' is not necessary as FormData handles it automatically
    },
    body: formData // Set the body of the request to the FormData object
  })
    .then((response) => response.json()) // Convert the response to JSON
    .then((data) => console.log(data)) // Log the response data
    .catch((error) => console.error("Error:", error)); // Log any errors that occur during the fetch operation
}

uploadFileToNinox(base64Data, fileName, APIKey, teamId, databaseId, tableId, recordId, fieldId);

 

Finally, I’m sharing a test application that implements both solutions.

 

#API upLoadFile.ninox

3 replies

null
    • szormpas
    • 2 mths ago
    • Reported - view

    Hi,
    I just wanted to thank you for sharing the above code with us. It's really beneficial and educational!
    I hope you don't mind me asking, but I'm a little confused about why we need to convert the file from base64 to a blob object if we choose to send it with the Fetch API in JavaScript.

      • Ninox developper
      • Jacques_TUR
      • 2 mths ago
      • Reported - view

       In this function, I chose to input content encoded in base64. This choice is motivated by the fact that the JavaScript script is called from Ninox, where handling binary content is difficult. Base64, being a text composed of ASCII characters (up to 64 characters), is easier to manage and less likely to degrade during manipulations in Ninox.

      Here’s how it works:

      1. In line 6, the base64 content is first converted to binary in the form of a string.
      2. Then, in line 8, this string is transformed into a byte array.
      3. This byte array is then used to create a Blob in line 12.
      4. Finally, this Blob is necessary to create a formData object in line 16.

      Although this example uses Ninox and base64, which might seem complex due to the multiple transformations, in a typical JavaScript usage scenario, the file is often already in binary array or Blob format.
      This example demonstrates how to send a file to Ninox in JavaScript from different formats.

      • szormpas
      • 2 mths ago
      • Reported - view

        Thanks for taking the time to explain this in more detail.

Content aside

  • 2 Likes
  • 2 mths agoLast active
  • 3Replies
  • 108Views
  • 2 Following