Προς το περιεχόμενο

Upload εικονας απο angular reactive form


slevinkelevra

Προτεινόμενες αναρτήσεις

Καλησπερα 
Χρησιμοποιω angular 6 και εχω φτιαξει μια reactive form για ανεβασμα textfields μαζι με μια εικονα. Την εικονα μπορεις να την κανεις drop μεσα σε ενα div ή κλικαρωντας στο ιδιο div ανοιγει file picker και επιλεγεις. Ειτε με τον ενα ειτε με τον αλλο τροπο την περνας στο file input και κανεις submit τη φορμα χωρις attach κτλ. Σε vanilla js γενικα το χω, σε angular/typescript που ειμαι μπετοβλακας, θελω τη βοηθεια σας. Να το παραθεσω κομματι-κομματι

 

<form [formGroup]="imageUpload" (ngSubmit)="imageUploadSubmitted()">
  <h3>Προσθηκη εικονας</h3>
  <div id="imageDrop" (click)='imageInput.click()' (drop)="drop($event)" (dragover)="allowDrop($event)" #imageDrop></div> 
  <input type="file" formControlName="imageInput" required #imageInput id="imageInput" name = 'imageInput' (change)='imageChange($event)'> 
  <input type="text" formControlName="imageName" required >   
  <button type="submit" [disabled]="!imageUpload.valid">Submit</button>
</form>

τιποτα ιδιαιτερο εδω. Απλα οταν κλικαρεις στο imageDrop, για να ανοιξει file picker, καλεις την imageChange απο το imageInput.click
Στην typescript
 

   allowDrop(e) {
    e.preventDefault();
  }

  drop(e) {
    e.preventDefault();  
    this.imageUpload.controls.imageInput.reset();  
    this.imageDrop.innerHTML="";               
    let input = this.imageUpload.controls.imageInput as any;
    input.value = e.dataTransfer.files[0];  
    this.checkfiles(e.dataTransfer.files);
  }

  imageChange(event){    
    this.imageDrop.innerHTML="";   
    this.checkfiles(event.target.files);    
  }

  checkfiles(files){      
    if (this.acceptedImageTypes[files[0].type] !== true){
      this.imageDrop.nativeElement.innerHTML="Not an image";	      
      return;	
    }
    else if (files.length>1){
      this.imageDrop.nativeElement.innerHTML="Only one image/time";		      
      return;	
    }    
    else { this.readfiles(files); }
  }

  readfiles(files){      
    const reader = new FileReader();
    let image = new Image();
    reader.onload =  (event) =>{      
      this.imageDrop.nativeElement.innerHTML="";		        
      let fileReader = event.target as FileReader;
      image.src = fileReader.result;
      image.width = 150; 
      this.imageDrop.nativeElement.appendChild(image);  
    };
    reader.readAsDataURL(files[0]);        
  }

  imageUploadSubmitted(){
    console.log('IMAGE VALUE - ',this.imageUpload.controls.imageInput.value);
    this.mapcmsService.uploadImage(this.imageUpload.value).subscribe((data) =>{
      if(data.success){                  
        alert('επιτυχης');
      }
      else{
        alert('σφαλμα. δοκιμαστε ξανα αργοτερα');
      }
    })
  }

 

drop function Αν κανεις drop δε ξερω αν εχεις πιο πριν επιλεξει κατι απο click/file picker. Οποτε ας το σβησω και ας ξαναδωσω τιμη. Η imageChange φροντιζει για αλλαγη μεσα απο click/file picker. Η checkfiles κανει 2 ελεγχους. H readfiles διαβαζει την εικονα και τη κανει preview στο div.
Η imageUploadSubmitted δουλευει οταν κανεις submit. Βασικο προβλημα. Αν εχεις επιλεξει εικονα απο click/file picker το IMAGE VALUE στη κονσολα ειναι ενα url και το Submit κουμπι ειναι ενεργο. Αν εχεις κανει drop το IMAGE VALUE στη κονσολα ειναι ενα object και το Submit κουμπι ειναι ανενεργο .
Αρα ειναι λαθος η τιμη. Δε ξερω πως να το φτιαξω.
Δοκιμασα να βγαλω αυτη τη λογικη απο τη drop Και να τη βαλω στη readfiles.

 

  drop(e) {
    e.preventDefault();  
    this.imageUpload.controls.imageInput.reset();  
    this.imageDrop.innerHTML="";               
    this.checkfiles(e.dataTransfer.files);
  }

  readfiles(files){  
    const reader = new FileReader();
    let image = new Image();
    reader.onload =  (event) =>{      
      this.imageDrop.nativeElement.innerHTML="";		        
      let fileReader = event.target as FileReader;
      image.src = fileReader.result;
      image.width = 150; 
      this.imageDrop.nativeElement.appendChild(image);  
      if (this.imageUpload.controls.imageInput.value==null) {   //<<addition             
        let input = this.imageUpload.controls.imageInput as any;        
        input.value = event.target.result;  
      }  //<<addition end
    };
    reader.readAsDataURL(files[0]);        
  }

Αυτο μου δινει error Property result does not exist on type EventTarget . Οποτε ξαναγυρναω οπως ηταν πριν (η λογικη στη drop παλι και τιποτα σχετικο στην readfiles) και συνεχιζω το τεσταρισμα με το click/file picker, που τουλαχιστον αφηνει το submit να γινει.

Στο node route με τη χρηση https://www.npmjs.com/package/formidable  

router.post('/upload/image',validate.required(),(req, res)=>{ 
  console.log('FILES - ',req.body.imageInput);
   
  const form = new formidable.IncomingForm();
  form.parse(req, function (err, fields, files) {        
    let oldpath = files.imageInput.path;
  });

To validate required τσεκαρει για το token του χρηστη. To FILES ειναι το ιδιο URL με αυτο απο τη φορμα . Μετα μου δινει

Cannot read property 'path' of undefined

για το oldpath, οποτε εκει σταματαει. Να υποθεσω οτι η ουτε η τιμη του imageInput δεν ειναι σωστη.

Παρολα αυτα, η φορμα γινετε submit μονο με αυτη τη τιμη. 

Παιδια ειλικρινα εχω κολλησει. Μια πως να γινει το switch απο την εικονα στο div μεσα στην file input, μια η τιμη του file input που δεν βγαζει νοημα στον node, δεν καταλαβαινω τι πρεπει να γινει, ουτε τι ακριβως φταει. Εχω προσπαθησει, βοηθηστε με λιγο να ξεκολλησω. Αν κατι δεν εξηγησα σωστα, πειτε μου.

Ευχαριστω πολυ. 


 

 

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!

Δημιουργία νέου λογαριασμού

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα
  • Δημιουργία νέου...