W
Wasp-lang3mo ago
Kalil

Simple File Upload

Hey. What would be the simplest way to add a simple file upload? Like profile picture editing I know there's multer, but it doesn't seem like such a straightforward solution compared to the other features of wasp It would be nice if there was something simpler like Adonis' AttachmentLite.
8 Replies
kapa.ai
kapa.ai3mo ago
Hi @Kalil. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- In Wasp, you can use multer for file uploads. While it might not be as straightforward as some other solutions, it is a popular middleware in Node.js for file management. Here's a simple setup with multer:
import multer from "multer";
import path from "path";

const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, "/tmp/tp-uploads");
},
filename: function (req, file, cb) {
const originalName = path.parse(file.originalname).name;
const extension = path.parse(file.originalname).ext;
const timestamp = Date.now();
const newFilename = `${originalName}_${timestamp}${extension}`;
cb(null, newFilename);
},
});

const upload = multer({ storage: storage });

export const addMiddleware = (config) => {
config.set("multer", upload.single("file"));
return config;
};

export const uploadFile = (req, res, context) => {
console.log(req.body);
console.log(req.file);
const file = req.file;
return res.json({
fileExists: !!file,
});
};
import multer from "multer";
import path from "path";

const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, "/tmp/tp-uploads");
},
filename: function (req, file, cb) {
const originalName = path.parse(file.originalname).name;
const extension = path.parse(file.originalname).ext;
const timestamp = Date.now();
const newFilename = `${originalName}_${timestamp}${extension}`;
cb(null, newFilename);
},
});

const upload = multer({ storage: storage });

export const addMiddleware = (config) => {
config.set("multer", upload.single("file"));
return config;
};

export const uploadFile = (req, res, context) => {
console.log(req.body);
console.log(req.file);
const file = req.file;
return res.json({
fileExists: !!file,
});
};
This code sets up multer to store files in a temporary directory and names them based on the original filename, a timestamp, and the file extension. The uploadFile function can be used to handle the file upload request, logging the request body and file, and responding with a JSON object indicating whether the file exists[^1^]. However, it's important to note that Wasp currently doesn't have a built-in way to handle file uploads as straightforward as some other frameworks like Adonis' AttachmentLite[^5^]. You might need to implement custom solutions depending on your specific use case. [^1^]: (Source: https://discord.com/channels/686873244791210014/1217681705511686194) [^5^]: (Source: https://github.com/wasp-lang/wasp/issues/494) ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ---------------------- Sorry @Kalil, I seem to be having a bit of trouble. Don't worry though, I've pinged my support and they will try to fix me up! :technologist: Perhaps try again in 15mins?
Kalil
Kalil3mo ago
yeah, it solves the problem, but requires boilerplate. I think we should think about how to simplify that since it's a very common fullstack feature
fustuk.
fustuk.3mo ago
well what is it that you really try to acomplish here?Make a custom endpoint that handles the file sent from the frontend and save it to s3 ?
Kalil
Kalil2mo ago
The other frameworks solutions (laravel, adonis etc) covers two or three things: 1. make the uploaded file easily accessible from the controller args withtout need to create a middleware Laravel example:
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class UserAvatarController extends Controller
{
public function upload(Request $request)
{
$avatar = $request.file('avatar');
}
}
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class UserAvatarController extends Controller
{
public function upload(Request $request)
{
$avatar = $request.file('avatar');
}
}
Adonis example:
import { HttpContext } from '@adonisjs/core/http'
export default class UserAvatarsController {
update({ request }: HttpContext) {
const avatar = request.file('avatar')
console.log(avatar)
}
}
import { HttpContext } from '@adonisjs/core/http'
export default class UserAvatarsController {
update({ request }: HttpContext) {
const avatar = request.file('avatar')
console.log(avatar)
}
}
2. Easily move files to a persistent location
await avatar.move(app.makePath('storage/uploads')
await avatar.move(app.makePath('storage/uploads')
3. Interfaces for easily persisting and serving files, where you can easily exchange the storage target (local, s3, etc) on a config file. Adonis provides Drive API and AttachmentLite API for that
MEE6
MEE62mo ago
Wohooo @Kalil, you just became a Waspeteer level 1!
Filip
Filip2mo ago
I know there's multer, but it doesn't seem like such a straightforward solution compared to the other features of wasp
Yeah, you are very right! We should be adding first-class support for that pretty soon, and I'm glad to hear it's sticking out - that souds that the rest of the framework is easy to use. I linked this thread from the issue where we're trakcing this feature to bump its priority: https://github.com/wasp-lang/wasp/issues/494
GitHub
Ability to serve and upload dynamic binary assets (images, pdfs) · ...
Wasp currently has no way to let users download dynamic binary assets nor upload them. This is a fairly common use case, so should be supported. Where these assets are stored is a related topic (da...
Filip
Filip2mo ago
And @fustuk., thanks for helping us out with the support!
Kalil
Kalil2mo ago
Nice
Want results from more Discord servers?
Add your server