#[SOLVED] storage.createFile` throws `source.on is not a function

31 messages · Page 1 of 1 (latest)

thorny badge
#

Is that the exact code you have?

Where is your code running? Server side or client side?

idle swallow
#

Its not.

Its running on the Server side.

I sincerely apologize for the redudant, unorganized and unprofessional way of requesting for support. Its my first time using discord to such extent

So I'm trying to upload an image using storage.createFile. But when I run it, it throws source.on is not a function. Below is what my code looks like

Also, there is an existing (but solved) issue posted in August, 2023, with the same title.


export async function createAppwriteSessionClient(token: string) {
  return new appwriteServerSdk.Client()
    .setEndpoint(process.env.NEXT_PUBLIC_APPWRITE_ENDPOINT!)
    .setProject(process.env.NEXT_PUBLIC_APPWRITE_PROJECT!)
    .setJWT(token);
}

// ...other code
// ...other code

setProperty(
  request,
  `locals.appwriteSessionClient`,
  await createAppwriteSessionClient(token!)
);

// ...other code
// ...other code

const transactionId = ID.unique();
const storage = new Storage(request.locals.appwriteSessionClient);

const uploadedCoverMedia = await storage.createFile(
  collections.GIFTCARDS.TRANSACTIONS.bucket,
  transactionId,
  order.coverMedia, // File Object gotten from formData of a request
  [
    Permission.read(Role.user(user.$id)),
    Permission.read(Role.team("VENDOR")),
    Permission.delete(Role.team("VENDOR")),
  ]
);
#

I just cant get a win today.

#

I should have checked the issue on github before coming here.

I did actually, except I forgot I was still on appwrite repo and not appwrite node sdk repo

I stumbled upon this https://github.com/appwrite/sdk-for-node/issues/32

It briefly mentions the current issue I'm facing but it's the problem has not been fixed (judging from my code)

GitHub

💭 Description The documentation for storageCreateFile seems wrong: https://appwrite.io/docs/server/storage?sdk=nodejs-default#storageCreateFile For the file parameter, there is only a string allowe...

thorny badge
idle swallow
#

Fistly,

``` is not a valid import path. The closest I could get to was to import from ```'node-appwrite/dist/inputFile'```
#

Secondly, from my understanding of the InputFile object documentation references and its type definition. It's function is to convert varying data types to a File object. Namely,files accessed within server environment, blobs...

Which is why I cant use the function on the file I'm receiving in my request via formData

thorny badge
idle swallow
#

"node-appwrite": "^14.1.0",

thorny badge
idle swallow
#

"node-appwrite": "^15.0.0"
Got the same error message

thorny badge
# idle swallow

is your function code in a nextjs server action or something? can you provide some more context?

idle swallow
#

I think the next thing to do is to simulate this in a remote environment to see if the problem is particular to my machine or code implementation. I'd rather just swap out using the Appwrite Storage API for something like Cloudinary just to hasten my development time.

What do you suggest we do now sir?

thorny badge
idle swallow
# thorny badge How are you pulling out the file from the request? What's the type of the file?
// What's the objective?
// -> Making a request to a public image file (temporary solution) from the frontend. The image is used in an API request call to the backend via FormData. The file object is then uploaded to a cloud storage bucket.

//
// Client (Browser) Environment
async function importPublicFile(
  publicFilePath: string,
  fileName?: string
): Promise<File> {
  const response = await fetch(publicFilePath);
  const blob = await response.blob();
  const [extractedFileName, _fileExtension] =
    publicFilePath.split("/").pop()?.split(".") || [];

  const finalFileName = fileName || extractedFileName;
  return new File([blob], finalFileName, { type: blob.type });
}

async function ReactComponent() {
  const coverMedia = await importPublicFile("/giftcard-default-cover.jpg");
  const formdataBody = new FormData();
  formdataBody.append("coverMedia", coverMedia);
  const { data } = await axios.post("/giftcards/sell", formdataBody);
}

//
// Server Environment
// api/giftcards/sell
async function NextjsRouteHandler() {
  const form = await request.formData();
  const coverMedia = form.get("coverMedia");

  const uploadedCoverMedia = await storage.createFile(
    collections.GIFTCARDS.TRANSACTIONS.bucket,
    transactionId,
    coverMedia!,
    [
      Permission.read(Role.user(user.$id)),
      Permission.read(Role.team("VENDOR")),
      Permission.delete(Role.team("VENDOR")),
    ]
  );
}

thorny badge
thorny badge
thorny badge
idle swallow
idle swallow
idle swallow
thorny badge
#

Instead, I used app router and created src/app/upload/route.tsx with this:

import { Client, Storage, ID } from "node-appwrite";

export async function POST(request: Request) {
  const formData = await request.formData();
  const file = formData.get("file");

  const client = new Client()
    .setEndpoint(process.env.ENDPOINT!)
    .setProject(process.env.PROJECT!);

  const storage = new Storage(client);

  try {
    await storage.createFile(process.env.BUCKET!, ID.unique(), file as File);
    return Response.json({ message: "Uploaded!" });
  } catch (error) {
    console.error(error);
    return Response.json({ message: "Failed to upload!" });
  }
}

and this uploaded the file fine

idle swallow
#

🤔 I'll get back to you. Thank you

idle swallow
#

@thorny badge If I had been more patient and trusted the code, this thread would have ended much sooner.

Turns out the issue was with my tsconfig file—it just needed some tweaking.

I relied on you to catch and fix the issue so much I didn’t think critically enough—rookie mistake.

Appreciate you standing firm on your suggestions and understanding. Thank you for your patience!
Enjoy the rest of your day, sir!

thorny badge
idle swallow
#

I had to update the following of my tsconfig file during the fix:

{
  "compilerOptions": {
    "target": "es2015", // Updated from "es5"
    "module": "Node16", // Updated from "esnext"
    "moduleResolution": "node16" // Updated from "node"
  }
}

Finally, implementing the file upload logic with this: #1204815353629245490 message

thorny badge
#

[SOLVED] storage.createFilethrowssource.on is not a function