SOLVED: Media manager API - how to upload image and update title and description fields in the front-end

I’m having trouble with
updating the metadata (title and description) when uploading an image in a gallery field type of my CMS.

Working in
Wix Editor, Dev Mode, CMS, Wix-media-manager API

Site link
private site

What I’m trying to do
For our neighborhood book group, I have a page for members to upload their book choice. The books by year CMS is one record for each year with a gallery field to store the 12 books for the year. The most recent record is the one I want updated when the user uploads the book cover image, title, and description. They are also adding the book, title, author, host name, date of meeting, and notes into another data collection. The books by year lets me display a bookshelf of book images for a particular year.
The Full list button takes them to a list of books with search capabilities to search by title, author, or host.

The metadata for the book image is title and description which is visible when the user hovers over the book.

What I’ve tried so far
For now, I am the one who has to add all of the images and books directly using the CMS in the dashboard. I really want the members to do this themselves in the front-end.

After much research to figure out how to do this, I ended up finding the AI Velo Assistant on this page https://dev.wix.com/docs/velo/apis/wix-media-v2/introduction which helped me create a backend module for the media manager and the Velo page code to go with it.

BACKEND CODE

// backend/updateMedia.web.js

import { Permissions, webMethod } from ‘wix-web-module’;

import wixData from ‘wix-data’;

export const updateCmsRecordWithMedia = webMethod(Permissions.Anyone, async (collectionName, imageUrl, imageTitle, imageDescription) => {

try {

// Query the collection to find the most recent record

const queryResults = await wixData.query(collectionName)

.descending(‘_createdDate’) // Sort by creation date in descending order

.limit(1) // Get only the most recent record

.find({ suppressAuth: true }); // Suppress authorization for backend operation Working with the Data API | Velo

if (queryResults.items.length === 0) {

throw new Error(“No records found in the collection.”);

}

const latestRecord = queryResults.items[0];

// Assuming your gallery field is named ‘gallery’ and stores an array of objects

// Each object should contain ‘src’, ‘title’, and ‘description’

const newGalleryItem = {

src: imageUrl,

title: imageTitle,

description: imageDescription

};

// Ensure the gallery field exists and is an array, then add the new item

if (!latestRecord.gallery) {

latestRecord.gallery = ;

}

latestRecord.galleryField.push(newGalleryItem);

// Update the record in the collection

const updatedRecord = await wixData.update(collectionName, latestRecord, { suppressAuth: true }); // Suppress authorization for backend operation Working with the Data API | Velo

return updatedRecord;

} catch (error) {

console.error(“Backend error updating CMS record:”, error);

throw new Error("Failed to update CMS record: " + error.message);

}

});

PAGE CODE

$w.onReady(function () {

// Initialize UI elements or event listeners

$w(‘#submitBookshelf’).onClick(async () => {

if ($w(“#uploadImage”).value.length > 0) {

$w(“#statusText”).text = “Uploading image…”;

try {

// Upload the file using the UploadButton’s uploadFiles() method

const uploadedFiles = await $w(“#uploadButton1”).uploadFiles();

const imageUrl = uploadedFiles[0].fileUrl; // Get the Wix Media URL

const imageTitle = $w(“#titleInput”).value;

const imageDescription = $w(“#descriptionInput”).value;

const collectionName = “Books”; // Replace with your actual collection name

$w(“#statusText”).text = “Updating CMS record…”;

// Call the backend function to update the CMS record

const updatedRecord = await updateCmsRecordWithMedia(collectionName, imageUrl, imageTitle, imageDescription);

$w(“#statusText”).text = “Upload and CMS update successful!”;

console.log(“Updated CMS record:”, updatedRecord);

// Optionally clear form fields

$w(“#uploadImage”).reset();

$w(“#titleInput”).value = “”;

$w(“#descriptionInput”).value = “”;

} catch (uploadError) {

$w(“#statusText”).text = “File upload or CMS update error.”;

console.error(“Error:”, uploadError.errorCode || uploadError.message);

console.error(uploadError.errorDescription || uploadError);

}

} else {

$w(“#statusText”).text = “Please choose a file to upload.”;

}

});

});

UI fields:

Upload button connected to the CMS gallery field.

Input title field and input description field (not connected to the CMS on the UI because it is metadata and not individual fields). I want to use the metadata because then when the gallery is displayed, the user will see the title and description when they hover over the image.

SUBMIT button. I have tried connecting it to the CMS and then using the onClick function to update the metadata. The image would be uploaded but the title and description metadata are not added. Nothing is updated when I removed the CMS connection from the SUBMIT button. When it is connected, I get the success message before it continues to try to update title and description. The status error is “File upload or CMS update error”

Extra context
It seems like I’m close. I’m not looking for editing the values already there, just letting our members upload a single image, title, and description.

I can’t believe I finally solved this! I had multiple errors in my code and trial and error and much anguish, it’s now working.

I rewrote the backend code (I started with Media Manager code and it was really about the gallery field). This is what I ended up with:

// backend/galleryOperations.web.js

import wixData from ‘wix-data’;

import { Permissions, webMethod } from ‘wix-web-module’;

import { elevate } from ‘wix-auth’; // Use elevate for permissions if needed

export const myCreateGalleryItem = webMethod(Permissions.Anyone, async (collectionId, itemId, galleryFieldName, newImageItem) => {

try {

// Elevate permissions if the collection’s write permissions are not set to ‘Anyone’

const elevatedQuery = elevate(wixData.query);

const elevatedUpdate = elevate(wixData.update);

// 1. Retrieve the existing item from the collection

const existingItem = await elevatedQuery(collectionId)

.eq(“_id”, itemId)

.find()

.then(results => results.items[0]);

if (!existingItem) {

throw new Error(`Item with ID ${itemId} not found in collection ${collectionId}.`);

}

// 2. Get the existing gallery array or initialize if it doesn’t exist

const currentGallery = existingItem[galleryFieldName] || ;

// 3. Append the new ImageItem to the gallery array

currentGallery.push(newImageItem);

// 4. Update the item in the collection with the modified gallery array

existingItem[galleryFieldName] = currentGallery;

const updatedItem = await elevatedUpdate(collectionId, existingItem);

console.log(“Successfully updated collection item:”, updatedItem);

return updatedItem;

} catch (error) {

console.error(“Backend error updating gallery field:”, error);

throw new Error(“Failed to update gallery field in CMS.”);

}

});

One thing that was wrong was the dataset I was trying to update. Here’s the updated page code:

import wixData from “wix-data”;

import { myCreateGalleryItem } from ‘backend/galleryOperations.web.js’; // Assuming a backend web module named galleryOperations.jsw

$w.onReady(function () {

$w(“#submitBookshelf”).onClick(async () => {

if ($w(“#uploadImage”).value.length > 0) {

try {

// 1. Upload the image using the Upload Button

const currentItem = $w(“#addBook2bookshelf”).getCurrentItem(); // Assuming getCurrentItem() is available or use getItems()

const itemId = currentItem._id;

$w(“#statusText”).text = itemId;

console.log(“Current item ID:”, itemId); // Store or use itemId as needed

const uploadedFiles = await $w(“#uploadImage”).uploadFiles();

const imageUrl = uploadedFiles[0].fileUrl; // Get the Wix Media URL

// 2. Get title and description from input fields

const title = $w(“#titleInput”).value;

const description = $w(“#descriptionInput”).value;

// 3. Construct the ImageItem object

const newImageItem = {

type: “image”, // As defined in $w.Gallery.items

title: title,

description: description,

src: imageUrl // The Wix Media URL

};

// Replace ‘yourCollectionId’ with the actual ID of your CMS collection

// Replace ‘yourItemId’ with the ID of the specific item in the collection to update

// Replace ‘galleryFieldName’ with the actual field key of your ‘Media Gallery’ field

const collectionId = “Books”;

const itemIdToUpdate = itemId;

const galleryFieldName = “gallery”;

// 4. Call backend web method to save the data

await myCreateGalleryItem(collectionId, itemIdToUpdate, galleryFieldName, newImageItem);

console.log(“Image, title, and description successfully added to gallery field.”);

$w(“#statusText”).text = “Image, title, and description successfully added to gallery field.”;

} catch (uploadError) {

console.error("File upload error: " + uploadError.errorCode, uploadError.errorDescription);

}

} else {

console.warn(“Please select an image to upload.”);

}

});

});