'Property 'create' does not exist on type { new (fileBits: BlobPart[], fileName: string, options?: FilePropertyBag | undefined):File; prototype: File}

I'm trying to create a file-sharing app using Multer, Cloudinary, Typescript, and Mongoose.

When I'm trying to save the files uploaded by users and the data like Filename, filesize, Secure_url & format to mongoose database it keeps throwing me this Typescript error Property 'create' does not exist on type.

Here's the code

File path server/routes/files.ts

import express from 'express'
import multer from 'multer'
import {UploadApiResponse, v2 as cloudinary} from 'cloudinary'

const router = express.Router();

const storage = multer.diskStorage({})

router.post
let upload = multer({
    storage
})

router.post("/upload", upload.single("myFile"), async (req, res) => {
    try {
        if (!req.file)
            return res.status(400).json({message: "Hey there! We need the file"})

        console.log(req.file);

        //storing the file in the variable "uploadedFile" and getting the api response from UploadApiResponse
        let uploadedFile: UploadApiResponse;

        try {
            //it's an async call. Here we're uploading the file
            uploadedFile = await cloudinary.uploader.upload(req.file.path, {
                folder: "shareme",
                resource_type: "auto"
            })
        } catch (error) {
            console.log(error.message)

            return res.status(400).json({message: "Cloudinary Error"})
        }

        const {originalname} = req.file 
        const {secure_url, bytes, format} = uploadedFile 

       constructor of the model and 2) Create method
        const file = await File.create({
            filename: originalname,
            sizeInBytes: bytes,
            secure_url,
            format,
        });
        res.status(200).json(file);
    } catch (error) {
        console.log(error.message);
        res.status(500).json({message: "Server Error :( "})
    }
})

export default router

server/model/File.ts

import mongoose,{Document}  from "mongoose";

const Schema = mongoose.Schema;

const fileSchema = new Schema({
        filename: {
            type: String,
            required: true
        },
        secure_url: {
            type: String,
            required: true
        },
        format: {
            type: String,
            required: true
        },
        sizeInByte: {
            type: String,
            required: true
        },
        sender: {
            type: String,
        },
        receiver: {
            type: String,
        },
    },
    {
        timestamps: true,
    }
);


// Interface  "IFile" has all the properties of mongoose document
interface IFile extends Document{
    filename: string,
    secure_url: string,
    sizeInByte: string,
    format: string,
    sender?: string,
    receiver?: string,
}

//typescript  IFILE interface
export default mongoose.model<IFile>("File", fileSchema)

server/config/db.ts

import mongoose from 'mongoose'

const connectDB = async () => {
    try {
        await mongoose.connect(process.env.MONGO_URI!, {
            useCreateIndex: true,
            useNewUrlParser: true,
            useFindAndModify: true,
            useUnifiedTopology: true,
        });
    } catch (error) {
        console.log("Connection Error", error.message);
    }

    //checking connection status
    const connection = mongoose.connection;
    //if connected to database
    if (connection.readyState>=1) {
        console.log("connected to database");
        return;
    }
    connection.on("error",()=>console.log("connection failed"));
}

export default connectDB;

server/server.ts

import express from 'express';
import dotenv from 'dotenv';
import cors from 'cors'
import connectDB from "./config/db";
import fileRoute from "./routes/files"
import {v2 as cloudinary} from 'cloudinary'

const app = express()
dotenv.config()

cloudinary.config({
    cloud_name:process.env.CLOUDINARY_API_CLOUD,
    api_key:process.env.CLOUDINARY_API_KEY,
    api_secret:process.env.CLOUDINARY_API_SECRET,
})

connectDB()


app.use(cors());
app.use(express.json())
app.use(express.urlencoded({
        extended: true,
    })
);

app.use("/api/files", fileRoute);

const PORT = process.env.PORT

app.listen(PORT, () => console.log(`Server is listening on PORT ${PORT}`));

package.json

{
  "name": "server",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "dev": "ts-node-dev --clear server.ts"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "cloudinary": "^1.26.3",
    "cors": "^2.8.5",
    "dotenv": "^10.0.0",
    "express": "^4.17.1",
    "mongoose": "^5.13.5"
  },
  "devDependencies": {
    "@types/cors": "^2.8.12",
    "@types/express": "^4.17.13",
    "@types/node": "^16.4.10",
    "ts-node-dev": "^1.1.8",
    "tsc": "^2.0.3",
    "typescript": "^4.3.5"
  }
}

I've attached an error photo

I've no idea what I'm missing here. I'm not able to store the data(Files) in mongoose which are extracted from multer (Grabbing the original name of the file) & Cloudinary (Grabbing the uploaded file). And this is my first time using mongoos.

Thanks in advance :)



Solution 1:[1]

the first thing you need to import the File from model in the path server/routes/files.ts

import File from '../models/File.ts'

and then in the same path server/routes/files.ts

change: constructor of the model and 2) Create method

const file = await File.create({
filename: originalname,
sizeInBytes: bytes,
secure_url, format, });

to: const file = new File({
    filename: originalname,
    sizeInBytes: bytes,
    secure_url,
    format,});
    res.status(200).json(file);

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1