Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Upload images with apollo-upload-client in React Native

I'm trying out Prisma and React Native right now. Currently I'm trying to upload images to my db with the package _apollo-upload-client (https://github.com/jaydenseric/apollo-upload-client). But it's not going so well.

Currently I can select an image with the ImagePicker from Expo. And then I'm trying to do my mutation with the Apollo Client:

await this.props.mutate({
  variables: {
    name,
    description,
    price,
    image,
  },
});

But I get the following error:

Network error: JSON Parse error: Unexpected identifier "POST"
- node_modules/apollo-client/bundle.umd.js:76:32 in ApolloError
- node_modules/apollo-client/bundle.umd.js:797:43 in error

And I believe it's from these lines of code:

const image = new ReactNativeFile({
  uri: imageUrl,
  type: 'image/png',
  name: 'i-am-a-name',
});

Which is almost identical from the their example, https://github.com/jaydenseric/apollo-upload-client#react-native.

imageUrl is from my state. And when I console.log image I get the following:

ReactNativeFile {
  "name": "i-am-a-name",
  "type": "image/png",
  "uri": "file:///Users/martinnord/Library/Developer/CoreSimulator/Devices/4C297288-A876-4159-9CD7-41D75303D07F/data/Containers/Data/Application/8E899238-DE52-47BF-99E2-583717740E40/Library/Caches/ExponentExperienceData/%2540anonymous%252Fecommerce-app-e5eacce4-b22c-4ab9-9151-55cd82ba58bf/ImagePicker/771798A4-84F1-4130-AB37-9F382546AE47.png",
}

So something is popping out. But I can't get any further and I'm hoping I could get some tips from someone.

I also didn't include any code from the backend since I believe the problem lays on the frontend. But if anyone would like to take a look at the backend I can update the question, or you could take a look here: https://github.com/Martinnord/Ecommerce-server/tree/image_uploads.

Thanks a lot for reading! Cheers.

Update

After someone asked after the logic in the server I have decided to past it below:

Product.ts

// import shortid from 'shortid'
import { createWriteStream } from 'fs'

import { getUserId, Context } from '../../utils'

const storeUpload = async ({ stream, filename }): Promise<any> => {
    // const path = `images/${shortid.generate()}`
    const path = `images/test`

    return new Promise((resolve, reject) =>
      stream
        .pipe(createWriteStream(path))
        .on('finish', () => resolve({ path }))
        .on('error', reject),
    )
  }

const processUpload = async upload => {
    const { stream, filename, mimetype, encoding } = await upload
    const { path } = await storeUpload({ stream, filename })
    return path
}

export const product = {
  async createProduct(parent, { name, description, price, image }, ctx: Context, info) {
    // const userId = getUserId(ctx)
    const userId = 1;
    console.log(image);
    const imageUrl = await processUpload(image);
    console.log(imageUrl);
    return ctx.db.mutation.createProduct(
      {
        data: {
            name,
            description,
            price,
            imageUrl,
            seller: {
                connect: { id: userId },
            },
        },
      },
      info
    )
  },
}
like image 603
Martin Nordström Avatar asked Mar 02 '18 02:03

Martin Nordström


2 Answers

Solution has been found.

I am a little embarrassed that this was the problem that I faced and I don't know if I should even accept this answer because of awkward I felt when I fixed the issue. But....

There was nothing wrong with my code, but there was a problem with the dependencies versions. I tried to backtrack everything on my app, so I decided to start from the beginning and create a new account. I expected it to work just fine, but I got this error:

Error: Cannot use GraphQLNonNull "User!" from another module or realm.

Ensure that there is only one instance of "graphql" in the node_modules
directory. If different versions of "graphql" are the dependencies of other
relied on modules, use "resolutions" to ensure only one version is installed.

https://yarnpkg.com/en/docs/selective-version-resolutions

Duplicate "graphql" modules cannot be used at the same time since different
versions may have different capabilities and behavior. The data from one
version used in the function from another could produce confusing and
spurious results.

Then I understand that something (that I didn't think of) was wrong. I checked my dependencies versions and compared them with Graphcool's example, https://github.com/graphcool/graphql-server-example/blob/master/package.json. And I noticed that my dependencies was outdated. So I upgraded them and everything worked! So that was what I had to do. Update my dependencies.

Moral of the story

Always, always check your damn dependencies versions...

like image 60
Martin Nordström Avatar answered Sep 21 '22 00:09

Martin Nordström


Crawling through your code, I have found this repository, which must be the front-end code if I am not mistaken?

As you've mentioned, apollo-upload-server requires some additional set-up and same goes for the front-end part of your project. You can find more about it here.

As far as I know, the problematic part of your code must be the initialisation of the Apollo Client. From my observation, you've put everything Apollo requires inside of src/index folder, but haven't included Apollo Upload Client itself.

I have created a gist from one of my projects which initialises Apollo Upload Client alongside some other things, but I think you'll find yourself out.

https://gist.github.com/maticzav/86892448682f40e0bc9fc4d4a3acd93a

Hope this helps you! 🙂

like image 24
maticzav Avatar answered Sep 21 '22 00:09

maticzav