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

createReadStream is not a function #256

Closed
maheraldous opened this issue Jul 9, 2021 · 7 comments
Closed

createReadStream is not a function #256

maheraldous opened this issue Jul 9, 2021 · 7 comments
Labels

Comments

@maheraldous
Copy link

Hello

I made a project for a few months ago and everything was working even the upload images but when I started the project again after a while and tried to upload a single image I get this error "createReadStream is not a function"

// index.js

const express = require('express');
const { graphqlUploadExpress } = require('graphql-upload');
const { ApolloServer, AuthenticationError } = require('apollo-server-express');
const { applyMiddleware } = require("graphql-middleware");
const { makeExecutableSchema } = require('graphql-tools');
...

  const schema = applyMiddleware(
    makeExecutableSchema({
      resolvers,
      typeDefs,
    }),
    // permissions
  );

  const app = express().use(
    graphqlUploadExpress({ maxFileSize: 10000000, maxFiles: 10 }),
  );

  const server = new ApolloServer({
    schema,
    context: async ({ req }) => {
      if (req) {
        // console.log('req: ', req.headers);
        const userAuth = await getUser(req);
        // console.log('userAuth: ', userAuth);
        return {  
          userAuth,
        };
      }
    },
    playground: {
      endpoint: '/graphql',
      settings: {
        'editor.theme': 'dark',
      },
    },
    uploads: false // Don't use it as true when it is => v14 node
  });

  server.applyMiddleware({ app });

  let PORT = 4000;
  app.listen( PORT, (error) => {
    if (error) return error;
    console.log(`🚀 Server listening on port http://localhost:${PORT}`);
    console.log(`GraphQL at http://localhost:${PORT}${server.graphqlPath}`);
    // open(
    //     `http://localhost:${PORT}${schema.graphqlPath}`,
    //     // {app: 'firefox'}
    // );
  });
}

// schema/index.js

const { gql, AuthenticationError } = require('apollo-server-express');
const shortid = require('shortid');
const fs = require('fs-extra');
...

const storeUpload = async ({ stream, filename, mimetype, encoding }) => {
  const id = shortid.generate();
  // Delete those '?!,:;' from the filename
  filename = filename.replace(/[?!,:;]/g, '');
  // Replace the whitespace with this '-'
  filename = filename.replace(/[\s+]/g, '-');
  // Add random id to the filename
  filename = `${id}-${filename}`;
  // Create path to the file
  const path = `images/${filename}`;

  return await new Promise((resolve, reject) =>
    stream.on('error', error => {
          // if (stream.truncated)
          // // Delete the truncated file.
          // fs.unlinkSync(path)
          // throw new Error("Please select a file with size 700 KB or less")
          // reject(error)
          fs.unlink(path, () => {
            reject(error);
          });
      })
      .pipe(fs.createWriteStream(path))
      .on("finish", () => resolve({
        // id,
        filename,
        path,
        mimetype,
        encoding
      }))
      .on("error", reject)
  );
};

const processUpload = async upload => {
  const { createReadStream, filename, mimetype, encoding } = await upload;
  if(upload.file.mimetype == 'image/jpeg' || upload.file.mimetype =='image/png' || upload.file.mimetype =='image/jpg') {
    const stream = await createReadStream();
    const file = await storeUpload({ stream, filename, mimetype, encoding });
    return file;
  } else {
    throw new Error("Please select a file with one of the following formats: jpeg, jpg, png");
  }
};

const typeDefs = gql`
  type File {
    _id: ID
    filename: String!
    path: String
    mimetype: String!
    encoding: String!
  }
  type Query {
    files: [File]
  }
  type Mutation {
    uploadFile(
      file: Upload!
    ): File!
  }
`;


const resolvers = {
Query: {
    files: async (_, args) => {
      const files = await FileMD.find()
      if (files == '') {
        return new Error(
          'There is no files'
        )
      }

      try {
        const filesArray = files.map(file => ({
          ...file._doc,
        }))
        return filesArray;
      } catch (err) {
        return err
      }
    },

Mutation: {
    uploadFile: async (_, args) => {
      console.log('args: ', args);
      console.log('args.file: ', args.file);
      fs.mkdir('images', { recursive: true }, err => {
        if (err) throw err;
      });

      const upload = await processUpload(args.file);
      console.log('upload: ', upload);
      const theFile = new FileMD(upload)
      const theFileSaved = await theFile.save()
      console.log('theFileSaved: ', theFileSaved);
      
      return theFileSaved;
    },}

}
}

Is the error there becuase that I updated from Node v12 to v14?

@jaydenseric
Copy link
Owner

I think you need to setup the GraphQLUpload scalar:

https://github.com/jaydenseric/graphql-upload#class-graphqlupload

@maheraldous
Copy link
Author

maheraldous commented Jul 10, 2021

Now I am getting this error apollographql/apollo-server#3508

It seems that I have to move back to Node v12 from v14

But is there any way to upload files without going back.

I like the schema-first GraphQL but yours is code-first GraphQL so is there a way to do it with schema-first
https://blog.logrocket.com/code-first-vs-schema-first-development-graphql/

@maheraldous
Copy link
Author

You are right it works now thank you very much

@jdgabriel
Copy link

In new version, same problem here. Any solutions?

Error:

**TypeError: createReadStream is not a function**

Code:

@Mutation((_) => Boolean)
addProfilePicture(
  @Arg("picture", () => GraphQLUpload)
  { createReadStream, filename }: FileUpload
): Promise<boolean> {
  return new Promise(async (resolve, reject) =>
    createReadStream()
      .pipe(createWriteStream(__dirname + `./${filename}`))
      .on("finish", () => resolve(true))
      .on("error", () => reject(false))
  );
}

@jdgabriel
Copy link

I find solution when use Fastify/TypeGraphQL

MichalLytek/type-graphql#37 (comment)

@taikishiino
Copy link

@jdgabriel @jaydenseric
Hi👋
I have written a related issue here.
meabed/graphql-upload-ts#108

@intellectualDarknet
Copy link

intellectualDarknet commented Sep 4, 2023

i my case order of arguments wasn't coinciding in resolver and service.
image
image
Make sure that you are passing correctly arguments and handling

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants