Skip to content

Fix: Make files ref iterable when exposed via defineExpose#40

Draft
Copilot wants to merge 7 commits into
masterfrom
copilot/fix-7928423f-8fd1-4d2c-b8c1-3f20806aef0c
Draft

Fix: Make files ref iterable when exposed via defineExpose#40
Copilot wants to merge 7 commits into
masterfrom
copilot/fix-7928423f-8fd1-4d2c-b8c1-3f20806aef0c

Conversation

Copy link
Copy Markdown

Copilot AI commented Oct 6, 2025

Problem

When using defineExpose to expose the files ref from a child component, users encountered the error "files is not iterable" and had to use awkward double .value unwrapping:

<!-- Child Component -->
<script setup>
const { handleFileInput, files, clearFiles } = useFileStorage()

defineExpose({
  files,
  handleFileInput,
  clearFiles
})
</script>

<!-- Parent Component -->
<script setup>
const childRef = ref()

// ❌ Required awkward double .value
for (const file of childRef.value.files.value) {
  console.log(file.name)
}
</script>

Solution

Made the files ref iterable by adding Symbol.iterator to it. Users can now iterate directly without the second .value:

<!-- Parent Component -->
<script setup>
const childRef = ref()

// ✅ Clean, ergonomic syntax
for (const file of childRef.value.files) {
  console.log(file.name)
}
</script>

Implementation

Added a createIterableRef<T>() helper function that:

  1. Creates a standard Vue ref
  2. Adds a Symbol.iterator property using Object.defineProperty
  3. Implements a generator function that yields items from the ref's value
function createIterableRef<T>(initialValue: T[]) {
  const refObj = ref<T[]>(initialValue)
  
  Object.defineProperty(refObj, Symbol.iterator, {
    value: function* () {
      yield* refObj.value
    },
    enumerable: false,
    configurable: true
  })
  
  return refObj
}

Backward Compatibility

100% backward compatible - all existing code continues to work:

  • files.value still returns the array
  • files.value[index] still works
  • Traditional .value.value access still supported
  • No breaking changes to the API

Testing

All tests passing (5/5 ✅):

  • ✅ Files ref is iterable without .value
  • ✅ Backward compatibility verified
  • ✅ Multiple files iteration works correctly
  • ✅ Exact defineExpose scenario from issue tested
  • ✅ Both old and new syntax work

Additional Changes

  • Updated README.md with "Using with defineExpose" section and examples
  • Added comprehensive unit tests (test/composable.test.ts, test/define-expose.test.ts)
  • Added playground test components for interactive verification
  • Added verification script to ensure implementation integrity
  • Configured vitest for proper testing environment

Fixes #[issue_number]

Original prompt

This section details on the original issue you should resolve

<issue_title>files is not iterable ٥:٣٨:٤٠ م</issue_title>
<issue_description>defineExpose is not woriking with files</issue_description>

Comments on the Issue (you are @copilot in this section)

@NyllRE Hey @mo7mad1996, I need more information on the way you've implemented the defineExpose function with Nuxt File Storage. It should be something similar to this:
<!-- Child Component -->
<script setup>
const { handleFileInput, files, clearFiles } = useFileStorage()

defineExpose({
  files,           // Expose the ref
  handleFileInput,
  clearFiles
})
</script>

<!-- Parent Component -->
<script setup>
const childRef = ref()

// Access like this:
const iterateFiles = () => {
  for (const file of childRef.value.files.value) {  // Note the .value.value
    console.log(file)
  }
}
</script>
```</body></comment_new>
</comments>
Fixes #39

✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

@NyllRE NyllRE requested review from NyllRE and Copilot October 6, 2025 18:35
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot wasn't able to review any files in this pull request.


Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Copilot AI and others added 6 commits October 6, 2025 18:40
Co-authored-by: NyllRE <52743522+NyllRE@users.noreply.github.com>
Co-authored-by: NyllRE <52743522+NyllRE@users.noreply.github.com>
…xpose

Co-authored-by: NyllRE <52743522+NyllRE@users.noreply.github.com>
Co-authored-by: NyllRE <52743522+NyllRE@users.noreply.github.com>
Co-authored-by: NyllRE <52743522+NyllRE@users.noreply.github.com>
Copilot AI changed the title [WIP] files is not iterable ٥:٣٨:٤٠ م Fix: Make files ref iterable when exposed via defineExpose Oct 6, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

files is not iterable ٥:٣٨:٤٠ م

3 participants