Estimadas(os),
Les escribo después de bastante tiempo de buscar y probar alternativas de solución, pero tosdas sin éxito... no soy un programador experto, pero con muchas ganas de aprender. Intento tener la posibilidad de subir más de un archivo a mi base en MongoDb, el código que adjunto permite seleccionar un sólo archivo por proyecto/documento. Agradezco la ayuda que me puedan dar orientándome con qué debería hacer.
Gracias.
Lado del BackEnd
Modelo:
'use strict'
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var ProjectSchema = Schema({
name:String,
description:String,
category: String,
year: Number,
langs:String,
image: [String]
//image:[{ img: String }]
});
module.exports = mongoose.model('Project', ProjectSchema);
Mi archivo “app.js” del Backend
'use strict'
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
// carga de los archivos de rutas
var project_routes = require('./routes/project');
// middlewares
app.use(bodyParser.urlencoded({extended:false}));
app.use(bodyParser.json());
// CORS
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Headers', 'Authorization, X-API-KEY, Origin, X-Requested-With, Content-Type, Accept, Access-Control-Allow-Request-Method');
res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, DELETE');
res.header('Allow', 'GET, POST, OPTIONS, PUT, DELETE');
next();
});
// rutas
app.use('/api', project_routes);
module.exports = app;
Rutas
'use strict'
var express = require('express');
var ProjectController = require('../controllers/project');
var router = express.Router();
var multipart = require('connect-multiparty');
var multipartMiddleware = multipart({uploadDir: './uploads'});
router.post('/upload-image/:id', multipartMiddleware, ProjectController.uploadImage);
router.get('/get-image/:image', ProjectController.getImageFile);
module.exports = router;
El Controlador
'use strict'
var Project = require('../models/project');
var fs = require('fs');
var path = require('path');
var controller = {
uploadImage:function(req, res){
var projectId = req.params.id;
var fileName = 'Imagen no subida...';
if (req.files){
var filePath = req.files.image.path;
var fileSplit = filePath.split('\\');
var fileName = fileSplit[1];
var extSplit = fileName.split('\.');
var fileExt = extSplit[1];
if (fileExt == 'png' || fileExt == 'jpg' || fileExt == 'jpeg' || fileExt == 'gif' || fileExt == 'pdf' || fileExt == 'docx'){
Project.findByIdAndUpdate(projectId, {image: fileName}, {new:true}, (err, projectUpdate) => {
if (err) return res.status(500).send({message: 'La imagen no se ha subido'});
if(!projectUpdate) return res.status(404).send({message:'El proyecto no existe y no se ha podido agregar el archivo'});
return res.status(200).send({
project:projectUpdate
});
});
}else{
fs.unlink(filePath, (err) => {
return res.status(200).send({message:'La extensión no es válida'});
});
}
}else{
return res.status(200).send({
message: fileName
});
}
},
getImageFile: function(req, res){
var file= req.params.image;
var path_file = './uploads/' + file;
fs.exists(path_file, (exists) => {
if(exists){
return res.sendFile(path.resolve(path_file));
}else{
return res.status(200).send({
message: 'No existe la imagen...'
});
}
});
}
};
module.exports = controller;
En el FrontEnd (Angular) Modelo
export class Project{
constructor(
public _id: string,
public name : string,
public description: string,
public category: string,
public year: number,
public langs: string,
public image: [ string ]
){}
}
CreateComponent
import { Component, OnInit } from '@angular/core';
import { Project } from '../../models/project';
import { ProjectService } from '../../services/project.service';
import { UploadService } from '../../services/upload.service';
import { Global } from '../../services/global';
@Component({
selector: 'app-create',
templateUrl: './create.component.html',
styleUrls: ['./create.component.css'],
providers: [ProjectService, UploadService]
})
export class CreateComponent implements OnInit {
public title: string;
public project: Project;
public save_project: any;
public status: string;
public filesToUpload: Array<File>;
constructor(
private _projectService: ProjectService,
private _uploadService: UploadService
) {
this.title = 'Crear proyecto';
// Creo una nueva instancia de mi modelo de datos ("Project")
this.project = new Project('', '', '', '', 2020, '', [''] );
}
ngOnInit() {
}
onSubmit(form){
console.log('Esto se va en el project')
console.log(this.project);
// Guardar datos básicos
this._projectService.saveProject(this.project).subscribe(
response => {
if(response.project){
// Subir la imagen... solo cuando la deba subir!
if(this.filesToUpload){
console.log( "El filesToUpload, en mi 'create.component.ts' tiene: " );
console.log( this.filesToUpload);
this._uploadService.makeFileRequest(Global.url + 'upload-image/' + response.project._id, [], this.filesToUpload, 'image').
then((result:any) => {
this.save_project = result.project;
this.status = 'success';
console.log('El result me entrega: ');
console.log(result);
// Con esto vacío el formulario una vez que ya se ha guardado
form.reset();
});
}else{
this.save_project = response.project;
this.status = 'success';
form.reset();
}
}else{
this.status = 'failed';
}
},
error => {
console.log(<any>error);
}
);
}
fileChangeEvent(fileinput:any){
console.log(' My fileinput entrega: ' );
console.log( fileinput );
this.filesToUpload = fileinput.target.files as Array<File>;
}
}
El Html
<p>
<label for="image">Imagen del proyecto</label>
<span class = "image" *ngIf="project.name" style="float: none;">
<img src="{{url + 'get-image/' + project.image}}" style="width: 100px;"/>
</span><br>
<script type="text/javascript">
alert("Hola Sebas");
</script>
<!-- La variable $event lleva todos las datos del input -->
<input type="file" multiple="true" name="image" placeholder="subir imagen" (change) = "fileChangeEvent($event)"/>
</p>
<input type = "submit" value="Enviar" [disabled] = "!projectForm.form.valid" />