Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug]: Validation Error expected asset(type = image).props.w: Expected number got undefined #3755

Closed
1 task done
Meqr1 opened this issue May 14, 2024 · 11 comments
Closed
1 task done
Labels
bug Something isn't working

Comments

@Meqr1
Copy link

Meqr1 commented May 14, 2024

What happened?

error

Uncaught (in promise) ValidationError: At asset(type = image).props.w: Expected number, got undefined
  • i am loading the users data that is stored in the localstorage by the editor.store.loadsnapshot function...

after the component mounts it shows me that error whenever i add a image...

i am saving the users data to the localsotrage every 1 second...

  • is there any way to fix this bug???
  • is there a better way to save and load files???

How can we reproduce the bug?

  1. renderer the Editor and add a image to it
  2. save the state of the store by store.storesnapshot() to the localStorage
  3. and now load the state from the localStorage

What browsers are you seeing the problem on?

Chrome

Contact Details

ayanmahajan41@gmail.com

Code of Conduct

  • I agree to follow this project's Code of Conduct
@Meqr1 Meqr1 added the bug Something isn't working label May 14, 2024
@Meqr1
Copy link
Author

Meqr1 commented May 14, 2024

Screenshot 2024-05-14 170938
Screenshot 2024-05-14 170944

this shows that there exists a w...
but it still shows a error...

@Meqr1
Copy link
Author

Meqr1 commented May 14, 2024

even after i remove the image from the canvas it still shows the same error...

@ds300
Copy link
Collaborator

ds300 commented May 17, 2024

Hello!

For images we store two records:

  • an image shape record, which stores information about where the image is in the document, how big it is, whether it has been cropped, etc.
  • an image asset record, which stores the actual image itself (either a URL or base 64) along with metadata about the image like it's native width and height.

This asset record is the one that is causing the problem for you. In your screenshot it's near the top
image.

I will investigate how it is possible for us to create snapshots with undefined w/h values in the assets props. In the meantime you can probably set them to 1 if they are undefined. I don't think the w/h properties are used after the shape record is created.

How can we reproduce the bug?

  1. renderer the Editor and add a image to it
  2. save the state of the store by store.storesnapshot() to the localStorage
  3. and now load the state from the localStorage

I wasn't able to reproduce the bug following these instructions, the snapshot's asset record has correct w/h properties. Can you share the JSON you get when calling store.getSnapshot()?

@Meqr1
Copy link
Author

Meqr1 commented May 20, 2024

sorry for the late reply but the W/H are actually available i.e: w = 173, h = 120...

{
    "document:document": {
        "gridSize": 10,
        "name": "",
        "meta": {},
        "id": "document:document",
        "typeName": "document"
    },
    "page:page": {
        "meta": {},
        "id": "page:page",
        "name": "Page 1",
        "index": "a1",
        "typeName": "page"
    },
    "asset:-1319438373": {
        "meta": {},
        "id": "asset:-1319438373",
        "type": "image",
        "typeName": "asset",
        "props": {
            "name": "Screenshot 2024-04-11 194432-png",
            "src": ".......",
            "w": 1000,
            "h": 600.7751937984495,
            "mimeType": "image/png",
            "isAnimated": false
        }
    },
    "shape:V2A6Cj5Id58jBG5MVhtBj": {
        "x": -236.5,
        "y": 126.48740310077528,
        "rotation": 0,
        "isLocked": false,
        "opacity": 1,
        "meta": {},
        "id": "shape:V2A6Cj5Id58jBG5MVhtBj",
        "type": "image",
        "props": {
            "w": 1000,
            "h": 600.7751937984495,
            "assetId": "asset:-1319438373",
            "playing": true,
            "url": "",
            "crop": null
        },
        "parentId": "page:page",
        "index": "a1",
        "typeName": "shape"
    }
}

this is the data

this is the code::

  useEffect(() => {
    const onMount = async () => {
      setLoading(true)
      if (sessionStorage.getItem('current_file')?.split('-')[1] !== 'D') return

      if (auth.currentUser) {
        let path
        if (
          JSON.parse(sessionStorage.getItem('teams')!).includes(
            sessionStorage.getItem('current_folder')
          )
        ) {
          path = `/teams/${sessionStorage.getItem('current_folder')}/data/${sessionStorage.getItem('current_file')}/data`
        } else {
          path = `/users/${auth.currentUser?.uid}/${sessionStorage.getItem('current_folder')}/${sessionStorage.getItem('current_file')}/data`
        }
        const FileRef = ref(db, path)

        const snap = await get(FileRef)
        const data = snap.val()
        if (data) {
          if (data.data) {
            store.loadSnapshot(data.data)
          }
        }
        setLoading(false)
      } else {
        const data = JSON.parse(
          localStorage.getItem('data') ? localStorage.getItem('data')! : '{}'
        )

        const FileData =
          data[sessionStorage.getItem('current_folder')!][
            sessionStorage.getItem('current_file')!
          ].data

        if (FileData) {
          if (FileData.data) {
            store.loadSnapshot(FileData.data)
          }
        }
        setLoading(false)
      }
    }

    onMount()

    document.addEventListener('storage', onMount)
    document.addEventListener('referesh-file', onMount)

    return () => {
      document.removeEventListener('referesh-file', onMount)
      document.removeEventListener('storage', onMount)
    }
  }, [store])

  useLayoutEffect(() => {
    const handleChange = async (snap: StoreSnapshot<TLRecord>) => {
      const parsedData = { data: snap }
      await uppload(
        JSON.stringify(parsedData).replace(/\.(?![0-9])/g, '-'),
        sessionStorage.getItem('current_file')!
      )
    }

    const cleanupFn = store.listen(
      throttle(() => {
        const snap = store.getSnapshot()
        handleChange(snap)
      }, 1000)
    )

    return () => {
      cleanupFn()
    }
  }, [store])

@ds300
Copy link
Collaborator

ds300 commented May 21, 2024

ah interesting thanks. Are you able to share the schema part of the snapshot too? I suspect the migrations are running when they needn't be.

@Meqr1
Copy link
Author

Meqr1 commented May 21, 2024

sure here is it...

{
    "schemaVersion": 2,
    "sequences": {
        "com-tldraw-store": 4,
        "com-tldraw-asset": 1,
        "com-tldraw-camera": 1,
        "com-tldraw-document": 2,
        "com-tldraw-instance": 24,
        "com-tldraw-instance_page_state": 5,
        "com-tldraw-page": 1,
        "com-tldraw-instance_presence": 5,
        "com-tldraw-pointer": 1,
        "com-tldraw-shape": 4,
        "com-tldraw-asset-bookmark": 1,
        "com-tldraw-asset-image": 3,
        "com-tldraw-asset-video": 3,
        "com-tldraw-shape-group": 0,
        "com-tldraw-shape-text": 1,
        "com-tldraw-shape-bookmark": 2,
        "com-tldraw-shape-draw": 1,
        "com-tldraw-shape-geo": 8,
        "com-tldraw-shape-note": 6,
        "com-tldraw-shape-line": 4,
        "com-tldraw-shape-frame": 0,
        "com-tldraw-shape-arrow": 3,
        "com-tldraw-shape-highlight": 0,
        "com-tldraw-shape-embed": 4,
        "com-tldraw-shape-image": 3,
        "com-tldraw-shape-video": 2
    }
}

@ds300

@ds300
Copy link
Collaborator

ds300 commented May 21, 2024

hm that looks wrong, those dashes should be dots. It should be like

{
    "schemaVersion": 2,
    "sequences": {
        "com.tldraw.store": 4,
        "com.tldraw.asset": 1,
        "com.tldraw.camera": 1,
        "com.tldraw.document": 2,
        "com.tldraw.instance": 24,
        "com.tldraw.instance_page_state": 5,
        "com.tldraw.page": 1,
        "com.tldraw.instance_presence": 5,
        "com.tldraw.pointer": 1,
        "com.tldraw.shape": 4,
        "com.tldraw.asset.bookmark": 1,
        "com.tldraw.asset.image": 3,
        "com.tldraw.asset.video": 3,
        "com.tldraw.shape.group": 0,
        "com.tldraw.shape.text": 1,
        "com.tldraw.shape.bookmark": 2,
        "com.tldraw.shape.draw": 1,
        "com.tldraw.shape.geo": 8,
        "com.tldraw.shape.note": 6,
        "com.tldraw.shape.line": 4,
        "com.tldraw.shape.frame": 0,
        "com.tldraw.shape.arrow": 3,
        "com.tldraw.shape.highlight": 0,
        "com.tldraw.shape.embed": 4,
        "com.tldraw.shape.image": 3,
        "com.tldraw.shape.video": 2
    }
}

do you have some kind of json key conversion logic in your app that might be replacing the dots with dashes?

@ds300
Copy link
Collaborator

ds300 commented May 21, 2024

oh yeah I see it here JSON.stringify(parsedData).replace(/\.(?![0-9])/g, '-'), you shouldn't be doing that

@ds300
Copy link
Collaborator

ds300 commented May 21, 2024

Gonna close this know. Let me know if removing the .replace(...) call there doesn't fix the problem and I'll reopen. Cheers 🙏🏼

@ds300 ds300 closed this as completed May 21, 2024
@Meqr1
Copy link
Author

Meqr1 commented May 21, 2024

yea it works now thanks @ds300 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants