It’s looking like an end of August / early September feature but can’t make any promises because we’re testing a new organization to iterate on existing integrations and the current priorities are supporting the new Xano Metadata API and Airtable’s personal access tokens.
Hi,
I’ve tried following this tutorial but receive this error:
Here is my JS code:
My goal:
Add file on UI → Upload file to supabase storage
Hey, you can do it in a wayyy more simple workflow, check this out
async function uploadImages(images) {
const storage = wwLib.wwPlugins.supabaseAuth.publicInstance.storage;
const promises = [];
for (let i = 0; i < images.length; i++) {
const image = images[i];
const randomName = generateRandomName(); // Implement your random name generation logic
const filePath = `property_1/bedroom_1/${randomName}.jpg`;
const promise = storage
.from('your bucket name here') // Your bucket name goes here
.upload(filePath, image, {
cacheControl: '3600',
upsert: true,
});
promises.push(promise);
}
// Wait for all upload promises to complete
await Promise.all(promises);
if(debug) console.log('Promises fulfilled.');
}
// Generate a random name function (you can customize this)
function generateRandomName() {
const randomString = Math.random().toString(36).substring(7);
return randomString;
}
// Call the uploadImages function
uploadImages(images)
.then(() => {
if(debug) console.log('Images uploaded.');
})
.catch((error) => {
console.error('Error uploading images:', error);
});
This is a funtion that lets you upload 1 or infinite amount of images. Like in this demo:
I use it in a formula like this
and then call it like this
I set the value
of images on change of the file upload like this, but you can do it with nocode too, it’s just a part of a bigger js code.
While Roberto’s method is one way of uploading multiple files one by one, from the error I think the main problem is not the method used but the missing element returned from querySelector
.
Replace document.querySelector('#my-image input')
with wwLib.getFrontDocument().querySelector('#my-image input')
and you should be good to go.
This will get you all the files within a folder, and it’s subfolders by recursively checking for items in the initial_path to the folder and in the bucket of your choice
async function retrieveItems(initialPath, bucket_name) {
const folderObject = {
data: [],
};
async function processItem(path, prev_path) {
const { data, error } = await supabase.storage.from(bucket_name).list((prev_path ? (prev_path + "/") : "") + path, {
limit: 100,
offset: 0,
});
if (!error && data) {
// Process the data or do something with it
const promises = [];
for (const item of data) {
if (item.id) folderObject.data.push((prev_path ? (prev_path + "/") : "") + path + "/" + item.name);
// Check for items without an 'id' and add them to promises
if (!item.id) {
const nestedPath = (prev_path ? (prev_path + "/") : "") + path;
promises.push(processItem(item.name, nestedPath)); // Use item.name instead of item.path
}
}
// Wait for all promises to resolve before returning
await Promise.all(promises);
} else {
console.error('Error fetching data:', error);
}
}
// Call the function with the initial path
await processItem(initialPath);
const { data, err } = await supabase
.storage
.from(bucket_name)
.createSignedUrls(folderObject.data, 60);
return data;
}
I received the same error.
double check the id of your element both in the code and the editor.
Which element exactly?
your file input
I see my issue. I have been using the drag and drop uploader and I assume the input type is different. What is the appropriate adjustment here?
If you look into dev tools, you should be aiming for the <input>
element.
This actually is kinda weird, because it seems like even if you go for the input, it is empty, so probably WeWeb handles those files in a different way?
@mander if you use the code I provided here
async function uploadImages(images, bucket, path) {
const storage = wwLib.wwPlugins.supabaseAuth.publicInstance.storage;
const promises = [];
for (let i = 0; i < images.length; i++) {
const image = images[i];
const randomName = generateRandomName(); // Implement your random name generation logic
const filePath = `${path}/${randomName}.jpg`;
const promise = storage
.from(bucket) // Your bucket name goes here
.upload(filePath, image, {
cacheControl: '3600',
upsert: true,
});
promises.push(promise);
}
// Wait for all upload promises to complete
await Promise.all(promises);
console.log('Promises fulfilled.');
}
// Generate a random name function (you can customize this)
function generateRandomName() {
const randomString = Math.random().toString(36).substring(7);
return randomString;
}
// Call the uploadImages function
uploadImages(variables[/* Input File Drop - value */ 'cdd23a87-baa8-4fe8-9782-69efde43c67b-value'], 'bucket_name', 'your_path/your_folder') // You just input your [ Input File Drop - value ] here
.then(() => {
console.log('Images uploaded.');
})
.catch((error) => {
console.error('Error uploading images:', error);
});
You can use the variable from the upload directly. Like this:
Seems to work,
No need to overcomplicate it by using queries and such.