Error when trying to create an event using Kybra

I have backend code written using Python Kybra for creating an event. The candid file is generated successfully but I can only create one event.
However, when I try to create a second event on my frontend, the following is printed on my console Create Event Error: Error: Call was rejected:
Request ID: 49d65677b609b916cb349a4349a541fdb9f378eab43494e0d7add45ec4f19b40
Reject code: 5
Reject text: Error from Canister bd3sg-teaaa-aaaaa-qaaba-cai: Canister called ic0.trap with message: TypeError: Expected type ‘int’ but ‘dict’ found.
Consider gracefully handling failures from this canister or altering the canister to handle exceptions.

at pollForResponse (@dfinity_agent.js?v=c3327adb:1589:13)
at async caller (@dfinity_agent.js?v=c3327adb:2082:29)
at async handleCreateEventbtn (CreateEvent.jsx:10:26)
at async handleSubmit (CreateEvent.jsx:82:9)

This is the code for my backend function to create an event
@update
def create_event(title: str, description: str, date: str, price: nat64, image: Vec[nat8]) → CreateConcert:
“”"
Create a new event with the given details.
“”"

image = get_images()
id = generate_id()

concert: Event = {
    "id": id,
    "title": title,
    "description": description,
    "date": date,
    "price": price,
    "image": image,
    
}

The image is processed successfully but for some reason the price cannot be processed by the backend when creating a second event.

Do you still need help with this? I suggest you reach out to @lastmjs.

Yes I still need help. I hope he’ll respond as you’ve already mentioned him🤞

I also encourage you to use the Python channel in the ICP Developer Discord. He usually is very prompt at responding to Kybra related questions there!

Please use the Discord channel or post all of the code neatly here, the error is guiding you to the problem, you have declared your return type for your update method, but you are not returning exactly that type. Please scrutinize your return value and return type and ensure that they match exactly.

This is my model for the Events :

class Event(Record):
    id: Principal 
    title: str
    description: str
    date: str
    price: nat64 
    image: Vec[nat8] 


@update
def create_event(title: str, description: str, date: str, price: nat64, image: Vec[nat8]) -> Event:
    """
    Create a new event with the given details.
    """

    image = get_images()
    id = generate_id()

    concert: Event = {
        "id": id,
        "title": title,
        "description": description,
        "date": date,
        "price": price,
        "image": image,
        
    }
    

    events.insert(concert['id'], concert)
    ic.print(f"Event ID: {concert['id']}, Data: {concert}")

    return {"Ok": concert}

This is how I am calling the backend functions:

import React, { useState } from 'react';
import { sentix_backend } from 'declarations/sentix_backend';
import Navbar from './Navbar';
import ImagesUpload from './ImageUpload';
import { Actor } from '@dfinity/agent';

const handleCreateEventbtn = async (title, description, date, price, image) => {
    try {
      const response = await sentix_backend.create_event(title, description, date, price, Array.from(image));
      alert("Event created successfully!");
    } catch (error) {
      alert("Failed to create event.");
      console.error("Create Event Error:", error);
    }
  };

function CreateEvent() {
    const [eventImage, setEventImage] = useState(null);
    const [uploadProgress, setUploadProgress] = useState(null);
    const [title, setTitle] = useState('');
    const [description, setDescription] = useState('');
    const [date, setDate] = useState('');
    const [price, setPrice] = useState(0);
    const [image, setImage] = useState([]);
    const [uploads, setUploads] = useState([]); 
    const [isLoadingImage, setIsLoadingImage] = useState(false); 
    const [progress, setProgress] = useState(null); 
    const [selectedImage, setSelectedImage] = useState(null);
    const [ actor, setActor ] = useState(null);

        const loadImages = async () => {
            try {
                const images = await sentix_backend.get_images();
                setUploads(images);
                console.log('Uploaded images:', images);
                alert('Image loaded successfully!');
            } catch (error) {
                alert('Error loading images. Please try again.');
                console.error('Error loading images:', error);
            }
        };

        const handleImageUpload = async () => {
            if (!selectedImage) return;
    
            setIsLoadingImage(true);
            const file = selectedImage.target.files[0];
            const reader = new FileReader();
        
            reader.onload = async () => {
              try {
                const imageData = new Uint8Array(reader.result);
                const chunks = Array.from(imageData);
                const id = await sentix_backend.upload_image(chunks);
                setImage(chunks);
                loadImages();
                setSelectedImage(null);
              } catch (error) {
                console.error('Error uploading image:', error);
              } finally {
                setIsLoadingImage(false);
              }
            };
        
            reader.readAsArrayBuffer(file);
          };

    const handleSubmit = async (e) => {
        e.preventDefault();
        if (!selectedImage) {
            alert("Please upload an image first");
            return;
        }
        await handleImageUpload();
        await handleCreateEventbtn(title, description, date, price, image);
    };

The output on my console is:

CreateEvent.jsx:13 Create Event Error: Error: Call was rejected:
  Request ID: 6421c8e5f8b8a0aabc1de77e6ace7e308e0b6439c07cd3815145539dbba71afe
  Reject code: 5
  Reject text: Error from Canister bd3sg-teaaa-aaaaa-qaaba-cai: Canister called `ic0.trap` with message: TypeError: Expected type 'int' but 'dict' found.
Consider gracefully handling failures from this canister or altering the canister to handle exceptions. See documentation: http://internetcomputer.org/docs/current/references/execution-errors#trapped-explicitly

    at pollForResponse (@dfinity_agent.js?v=0dd6157b:1589:13)
    at async caller (@dfinity_agent.js?v=0dd6157b:2082:29)
    at async handleCreateEventbtn (CreateEvent.jsx:9:24)
    at async handleSubmit (CreateEvent.jsx:75:9)

This is the Github repo

You are returning a dictionary with an Ok, when it’s expecting just an event

My bad, I overlooked that. Thank you

1 Like