I’m working in Wix Studio. I am creating code that calls up information about a pet from the Adopt-A-Pet website using an API key, API URL, and Shelter ID. My site link is www.positivepawsbhc.org/adopt.
All of my code is working except for the image. I am unable to get an image of the pet to appear in the repeater. Adopt-A-Pet is giving me a placeholder image instead of a real image of the pet.
This is my backend code:
import { fetch } from ‘wix-fetch’;
import { getSecret } from ‘wix-secrets-backend’;
import { mediaManager } from ‘wix-media-backend’;
export async function proxyImageToWix(imageUrl) {
if (!imageUrl || imageUrl.includes(‘PDP-NoPetPhoto’)) {
console.warn(‘proxyImageToWix was called with a null, empty, or placeholder URL.’);
return null;
}
console.log(`Attempting to import image from URL: ${imageUrl}`);
try {
const uploadedImage = await mediaManager.importFile(
imageUrl, // First parameter: The external URL
‘image’, // Second parameter: The file type
{} // Third parameter: An empty options object
);
if (uploadedImage && uploadedImage.fileUrl) {
console.log(`Successfully imported image. New Wix fileUrl: ${uploadedImage.fileUrl}`);
if (!uploadedImage.fileUrl.startsWith(‘wix:image://v1/’)) {
console.error(`Unexpected Wix fileUrl format: ${uploadedImage.fileUrl}`);
}
return uploadedImage.fileUrl;
} else {
console.error(`Import successful for ${imageUrl}, but no fileUrl was returned.`);
return null;
}
} catch (error) {
console.error(`Error importing image from URL: ${imageUrl}`, error);
return null;
}
}
export async function getShelterPets() {
const apiKey = await getSecret(‘AdoptAPet_API’);
const shelterId = ‘238464’;
const url = `https://api.adoptapet.com/search/pets_at_shelter?key=${apiKey}&shelter_id=${shelterId}
const fallbackImageUrl = ‘wix:image://v1/4b9983_b93d395a43924f07a77e0f2f703698de~mv2.jpg’;
console.time(‘getShelterPets’);
console.log(‘Starting getShelterPets function…’);
try {
const httpResponse = await fetch(url, { method: ‘GET’ });
console.log(`Adopt-a-Pet API fetch completed. Status: ${httpResponse.status}`);
if (httpResponse.ok) {
const apiData = await httpResponse.json();
console.log(‘Adopt-a-Pet API response received.’);
if (apiData.status === ‘ok’ && apiData.pets) {
console.log(`Found ${apiData.pets.length} pets in the API response.`);
const repeaterDataPromises = apiData.pets.map(async pet => {
const externalImageUrl = pet.images?.[0]?.original_url;
let wixImageUrl;
// Check if a valid URL exists AND it’s not a placeholder
if (externalImageUrl && !externalImageUrl.includes(‘PDP-NoPetPhoto’)) {
console.log(`Valid image URL found for pet ID ${pet.pet_id}: ${externalImageUrl}`);
wixImageUrl = await proxyImageToWix(externalImageUrl);
} else {
console.warn(`No valid image or found placeholder URL for pet ID ${pet.pet_id}. Using fallback image.`);
wixImageUrl = fallbackImageUrl;
}
return {
_id: pet.pet_id.toString(),
petName: pet.pet_name,
petImage: wixImageUrl || fallbackImageUrl,
petBreed: pet.primary_breed,
petAge: pet.age,
petS ex: pet.s ex,
};
});
const repeaterData = await Promise.all(repeaterDataPromises);
console.log(‘All images processed and repeater data prepared.’);
console.timeEnd(‘getShelterPets’);
return repeaterData;
} else {
console.error(‘Adopt-a-Pet API returned a non-OK status or missing data:’, apiData.error_message);
console.timeEnd(‘getShelterPets’);
return ;
}
} else {
console.error(`Fetch request failed with status: ${httpResponse.status} ${httpResponse.statusText}`);
console.timeEnd(‘getShelterPets’);
return ;
}
} catch (err) {
console.error(‘An unexpected error occurred during API fetch or processing:’, err);
console.timeEnd(‘getShelterPets’);
return ;
}
}
This is my front end code:
import { getShelterPets } from ‘backend/AdoptAPet.jsw’;
$w.onReady(function () {
setupRepeater();
fetchAndPopulateRepeater();
});
// Configure how each repeater item should be populated
function setupRepeater() {
$w(‘#AdoptablePets’).onItemReady(($item, itemData, index) => {
$item(‘#petImage’).src = itemData.petImage;
$item(‘#petImage’).show();
// Log the data to the console for debugging
console.log(`Pet Name: ${itemData.petName}, Image URL: ${itemData.petImage}`);
$item(‘#petName’).text = `Name: ${itemData.petName}`;
$item(‘#petBreed’).text = `Breed: ${itemData.petBreed}`;
$item(‘#petex’).text = `S ex: ${itemData.petex}`;
$item(‘#petAge’).text= `Age: ${itemData.petAge}`;
});
}
// Fetch the data and assign it to the repeater
async function fetchAndPopulateRepeater() {
console.log(“Attempting to fetch data from the backend.”);
try {
const fetchedPetData = await getShelterPets();
if (fetchedPetData.length > 0) {
$w(‘#AdoptablePets’).data = fetchedPetData;
} else {
console.log(“No pet data was returned.”);
// Add code here to show a “No pets found” message
}
} catch (err) {
console.error(“Error fetching data for repeater:”, err);
// Display an error message to the user
}
}
Here is a link to the API documentation. https://www.adoptapet.com/public/apis/pet_list.html#api_features
username pet_list_api, password jradmarbeq
Link to Adopt-A-Pet page Available Pets at Positive Paws BHC in Bullhead City, AZ - Adoptapet.com
This is the image url for one of the pets https://media.adoptapet.com/image/upload/d_PDP-NoPetPhoto_Dog.png/c_auto,g_auto,w_358,ar_142:135,dpr_2/f_auto,q_auto/1251332631
It’s telling me there is no photo or giving me a place holder, and so my code replaces it with my custom placeholder.
I’m not an expert coder. AI wrote this code for me, but I understand it more than the average person. Customizing a pet list on a website using an API would be pretty worthless if the API didn’t allow the retrieval and display of the pets photo, so I’m can’t imagine that the Adopt-A-Pet API doesn’t include that feature. I keep thinking that since the image URL is a substructure, I’m missing a step to that gets to that structure.
Any help would be greatly appreciated. Thank you so much!



