0

I'm trying to make a simple multiple file upload using solid.js:

import { createSignal } from 'solid-js';

function App() {

  const [files, setFiles] = createSignal([]);

  function handleFileChange(event) {
    const selectedFiles = Array.from(event.target.files);
    setFiles(() => selectedFiles);
    selectedFiles.forEach(file => {
      console.log('Selected file:', file.name);
      console.log('File size:', file.size);
    });
  }

  async function uploadFiles() {
    const formData = new FormData();
    for (const file of files()) {
      formData.append('file', file);
    } 

    // Send the file to the server using fetch or your preferred method
      try {
        const response = await fetch('http://127.0.0.1:8090/upload', {
          method: 'POST',
          body: formData,
        });
        console.log('File uploaded successfully');
      } catch (error) {
       console.error('Error uploading file:', error);
      }
  }

 
  return (
    <div class={styles.App}>
        <div class={styles.item}>
      
          <input type="file" multiple onChange={handleFileChange} />
          <button onclick={uploadFiles}>Upload</button>
         </div>
    </div>
  );
}

export default App;

In the console I see the file names and their sizes:

Selected file: Track01.mp3
App.jsx:16 File size: 1650939
App.jsx:15 Selected file: Track02.mp3
App.jsx:16 File size: 1919269
App.jsx:15 Selected file: Track03.mp3
App.jsx:16 File size: 1338305
App.jsx:37 File uploaded successfully

But in the backend empty files is received:

files: []

And no file is saved in the destination path.

Then I read that createSignal does not allow arrays so I used const [files, setFiles] = createStore([]); and for (const file of files) respectively, buts still got the same result.

I've also tried uploadFiles snycronously, but without luck.

I'm new to solid.js. Just wondering why this happens and how can I fix it?

blnks
  • 600
  • 5
  • 15
  • When I use `for (const file of files()`, I get this error: `Uncaught (in promise) TypeError: files is not iterable`. As far as I know you should invoke signal values in solid.js as they are treated as functions. – blnks Jun 07 '23 at 01:31

2 Answers2

0

You don't need to use createStore, or a signal or an effect. You can make API calls directly, without all this additional cruft, and use a signals to track the status of that call so that you can show some feedback like a loading indicator, success or fail message.

Here you can find a detailed answer: https://stackoverflow.com/a/74590574/7134134

snnsnn
  • 10,486
  • 4
  • 39
  • 44
-1

Needed to use createStore instead to keep track of upload files which accepts arrays directly contrary to createSignle which needs some trickery to do so. Also had small problem in the backend to accept file. So I put the complete solid.js part here, as I could not find a working example myself:

import { createStore } from "solid-js/store";

function App() {

  const [files, setFiles] = createStore([]);
      function handleFileChange(event) {
        const selectedFiles = Array.from(event.target.files);
        setFiles( ()=> selectedFiles );
      }
    
      async function uploadFiles() {
        const formData = new FormData();
        for (const file of files) {
          formData.append('file', file);
    
        } 
    ``
           try {
            const response = await fetch('http://127.0.0.1:8090/upload', {
              method: 'POST',
              body: formData,
            })
            .then(response => response.json())
            .then(data => {
              console.log('response json:' , data); // Log the JSON response

            })
      
          } catch (error) {
            console.error('Error uploading file:', error);
          }
     
      }

  return (
    <div class={styles.App}>
          <input type="file" multiple onChange={handleFileChange} />
          <button onclick={uploadFiles}>Upload</button>
    </div>
  );
}

export default App;
blnks
  • 600
  • 5
  • 15