q-file-picker component with express js help



  • Hello

    I am new to quasar and will appreciate if someone can help on this.

    I am using the q-file-picker component like this

    <template>
      <div class="q-pa-md column items-start q-gutter-y-md">
        <q-file
          :value="files"
          @input="updateFiles"
          label="Pick files"
          outlined
          multiple
          :clearable="!isUploading"
          style="max-width: 400px"
        >
          <template v-slot:file="{ index, file }">
            <q-chip
              class="full-width q-my-xs"
              :removable="isUploading && uploadProgress[index].percent < 1"
              square
              @remove="cancelFile(index)"
            >
              <q-linear-progress
                class="absolute-full full-height"
                :value="uploadProgress[index].percent"
                :color="uploadProgress[index].color"
                track-color="grey-2"
              />
    
              <q-avatar>
                <q-icon :name="uploadProgress[index].icon" />
              </q-avatar>
    
              <div class="ellipsis relative-position">
                {{ file.name }}
              </div>
    
              <q-tooltip>
                {{ file.name }}
              </q-tooltip>
            </q-chip>
          </template>
    
          <template v-slot:after v-if="canUpload">
            <q-btn
              color="primary"
              dense
              icon="cloud_upload"
              round
              @click="upload"
              :disable="!canUpload"
              :loading="isUploading"
            />
          </template>
        </q-file>
      </div>
      <!--
        <div class="col-4 q-pa-sm">
          <q-uploader
            url="http://localhost:30035/uploads"
            label="Upload files"
            color="purple"
            square
            flat
            bordered
          />
        </div>
      </div>
      -->
    </template>
    
    <script>
    import api from "../../api";
    
    export default {
      data() {
        return {
          files: null,
          uploadProgress: [],
          uploading: null
        };
      },
      computed: {
        isUploading() {
          return this.uploading !== null;
        },
    
        canUpload() {
          return this.files !== null;
        }
      },
    
      methods: {
        cancelFile(index) {
          this.uploadProgress[index] = {
            ...this.uploadProgress[index],
            error: true,
            color: "orange-2"
          };
        },
    
        async updateFiles(files) {
          this.files = files;
          this.uploadProgress = (files || []).map(file => ({
            error: false,
            color: "green-2",
            percent: 0,
            icon:
              file.type.indexOf("video/") === 0
                ? "movie"
                : file.type.indexOf("image/") === 0
                ? "photo"
                : file.type.indexOf("audio/") === 0
                ? "audiotrack"
                : "insert_drive_file"
          }));
        },
        async upload() {
          clearTimeout(this.uploading);
    
          const allDone = this.uploadProgress.every(
            progress => progress.percent === 1
          );
    
          var file = this.files[0];
          var fileName = file.name;
    
          const objResponse = await api.uploadFile(file);
          console.log("objResponse in app is ", objResponse);
    
          this.uploadProgress = this.uploadProgress.map(progress => ({
            ...progress,
            error: false,
            color: "green-2",
            percent: allDone === true ? 0 : progress.percent
          }));
    
          let done;
          this.uploading =
            done !== true ? setTimeout(this.__updateUploadProgress, 300) : null;
        },
    
        __updateUploadProgress() {
          let done = true;
    
          this.uploadProgress = this.uploadProgress.map(progress => {
            if (progress.percent === 1 || progress.error === true) {
              return progress;
            }
    
            const percent = Math.min(1, progress.percent + Math.random() / 10);
            const error = percent < 1 && Math.random() > 0.95;
    
            if (error === false && percent < 1 && done === true) {
              done = false;
            }
    
            return {
              ...progress,
              error,
              color: error === true ? "red-2" : "green-2",
              percent
            };
          });
    
          this.uploading =
            done !== true ? setTimeout(this.__updateUploadProgress, 300) : null;
        }
      },
    
      beforeDestroy() {
        clearTimeout(this.uploading);
      }
    };
    </script>
    
    

    and in my express code i am doing like this

    
      app.post('/uploads', function (req, res) {
        if (!req.files || Object.keys(req.files).length === 0) {
          return res.status(400).send('No files were uploaded.');
        }
    
    
        // The name of the input field (i.e. "sampleFile") is used to retrieve the uploaded file
        let sampleFile = req.files[Object.keys(req.files)[0]]; //returns 'someVal'
    
        console.log("sampleFile is ", sampleFile);
    
        // Use the mv() method to place the file somewhere on your server
        sampleFile.mv(__dirname + '/uploads/' + sampleFile.name, function (err) {
          if (err)
            return res.status(500).send(err);
    
          res.send('File uploaded!');
        });
      });
    

    I am not able to connect the both, the express code works ok with q-uploader but i would like to use q-file-picker as above for my project…

    can someone please help.

    Thanks
    GS



  • Sorry, no solution, but a related question: How can the file picker default folder be set to something other than __dirname? I have not been able to find an answer in the doco or Forum. This requirement would seem to be common, so including an example in the file picker documentation where the default folder is set would be appreciated.



  • I actually fixed this back then, sorry i did not posted here let me post now so it may help someone need this.

    <template>
      <div>
        <q-file
          :value="files"
          @input="updateFiles"
          :label="label"
          outlined
          multiple
          :clearable="!isUploading"
        >
          <template v-slot:file="{ index, file }">
            <q-chip
              class="full-width q-my-xs"
              :removable="isUploading && uploadProgress[index].percent < 1"
              square
              @remove="cancelFile(index)"
            >
              <q-linear-progress
                class="absolute-full full-height"
                :value="uploadProgress[index].percent"
                :color="uploadProgress[index].color"
                track-color="grey-2"
              />
    
              <q-avatar>
                <q-icon :name="uploadProgress[index].icon" />
              </q-avatar>
    
              <div class="ellipsis relative-position">
                {{ file.name }}
              </div>
    
              <q-tooltip>
                {{ file.name }}
              </q-tooltip>
            </q-chip>
          </template>
    
          <template v-slot:after v-if="canUpload">
            <q-btn
              color="primary"
              dense
              icon="cloud_upload"
              round
              @click="upload"
              :disable="!canUpload"
              :loading="isUploading"
            />
          </template>
        </q-file>
      </div>
      <!--
        <div class="col-4 q-pa-sm">
          <q-uploader
            url="http://localhost:30035/uploads"
            label="Upload files"
            color="purple"
            square
            flat
            bordered
          />
        </div>
      </div>
      -->
    </template>
    
    <script>
    import api from "@/api";
    import axios from "axios";
    
    export default {
      name: "Uploader",
      props: {
        type: {
          type: String,
          default: ""
        }
      },
      data() {
        return {
          files: null,
          uploadProgress: [],
          uploading: null
        };
      },
      computed: {
        label() {
          return "Upload your " + this.type;
        },
        isUploading() {
          return this.uploading !== null;
        },
    
        canUpload() {
          return this.files !== null;
        }
      },
    
      methods: {
        cancelFile(index) {
          this.uploadProgress[index] = {
            ...this.uploadProgress[index],
            error: true,
            color: "orange-2"
          };
        },
    
        async updateFiles(files) {
          this.files = files;
    
          if (this.files.length) {
            let objFile = this.files[0];
            if (this.type == "Video") {
              if (objFile.type.indexOf("video/") !== 0) {
                this.$q.notify({
                  color: "red-5",
                  textColor: "white",
                  icon: "warning",
                  message: "Please select a valid VIDEO to upload."
                });
    
                return false;
                event.preventDefault();
              }
            } else {
              if (objFile.type.indexOf("image/") !== 0) {
                this.$q.notify({
                  color: "red-5",
                  textColor: "white",
                  icon: "warning",
                  message: "Please select a valid IMAGE to upload."
                });
                return false;
                event.preventDefault();
              }
            }
    
            this.uploadProgress = (files || []).map(file => ({
              error: false,
              color: "green-2",
              percent: 0,
              icon:
                file.type.indexOf("video/") === 0
                  ? "movie"
                  : file.type.indexOf("image/") === 0
                  ? "photo"
                  : file.type.indexOf("audio/") === 0
                  ? "audiotrack"
                  : "insert_drive_file"
            }));
          }
        },
        upload() {
          clearTimeout(this.uploading);
    
          const config = {
            headers: {
              "Content-Type": "multipart/form-data"
            },
            onUploadProgress: progressEvent => {
              console.log(progressEvent.loaded);
              this.uploadProgress[0].error = false;
              this.uploadProgress[0].color = "green-2";
              var percent = progressEvent.loaded / progressEvent.total;
              this.uploadProgress[0].percent = percent;
              console.log(
                "Progress:",
                progressEvent.loaded,
                "/",
                progressEvent.total,
                percent + "%"
              );
            }
          };
    
          var file = this.files[0];
          //var fileName = file.name;
          var strType = this.type;
    
          var formData = new FormData();
          formData.append("file", file);
          // You should have a server side REST API
    
          var _this = this;
    
          axios
            .post(api.getAPIBaseUrl() + "/uploads", formData, config)
            .then(function(objResponse) {
              objResponse.data.strType = strType;
              console.log("SUCCESS!!", objResponse.data);
              _this.$emit("uploaded", objResponse.data);
            })
            .catch(function(err) {
              console.log("FAILURE!!", err);
              _this.$emit("uploaded", err);
            });
        }
    
        /*
        __updateUploadProgress() {
          let done = true;
    
          this.uploadProgress = this.uploadProgress.map(progress => {
            if (progress.percent === 1 || progress.error === true) {
              return progress;
            }
    
            const percent = Math.min(1, progress.percent + Math.random() / 10);
            const error = percent < 1 && Math.random() > 0.95;
    
            if (error === false && percent < 1 && done === true) {
              done = false;
            }
    
            return {
              ...progress,
              error,
              color: error === true ? "red-2" : "green-2",
              percent
            };
          });
    
          this.uploading =
            done !== true ? setTimeout(this.__updateUploadProgress, 300) : null;
        }
        */
      },
    
      beforeDestroy() {
        clearTimeout(this.uploading);
      }
    };
    </script>
    
    

    in express

    
      app.post('/uploads', function (req, res) {
    
    
        if (!req.files || Object.keys(req.files).length === 0) {
          return res.status(400).send('No files were uploaded.');
        }
    
        // The name of the input field (i.e. "objFile") is used to retrieve the uploaded file
        let objFile = req.files[Object.keys(req.files)[0]]; //returns 'someVal'
    
        objFile.name = objFile.md5 + "." + mime.getExtension(objFile.mimetype);
    
        console.log("objFile is ", objFile);
    
        // Use the mv() method to place the file somewhere on your server
        objFile.mv(__dirname + '/uploads/' + objFile.name, function (err) {
          if (err) {
            res.status(500).json({ blnOK: false, msg: err.message });
          }
    
          var objResponse = {};
          objResponse.blnOK = true;
          objResponse.objFile = objFile;
          res.json(objResponse);
        });
      });
    

    please note i am using “express-fileupload” for file uploading


Log in to reply