1

I have user.component.html and user.component.ts All examples I found were in html this way <input type="file" /> I don't want to use this style. I have in my html file:

<button type="button" class="btn" (click)="openPicture()" Browse </button>

Below is the function on ts file:

  public openPicture() {
    //for testing
    console.log('button clicked to open picture');

    var picture = browse.the.picture.and.assing.to.this.variable;

    //another test, see on console if picture is read
    console.log('%c       ', 'font-size: 100px; background: {{picture}} no-repeat;');
    // Later display picture variable on html and save to database or do anything desired.
}

I have found an example on stackoverflow with angular/material but I dont have this module. Is there any other alternative way, without installing any extra package to solve this?

Anarkie
  • 657
  • 3
  • 19
  • 46

3 Answers3

5

you can implement like this

<input type="file" style="display: none" #file (change)="fileChange($event)"/>
<button type="button" class="btn" (click)="file.click()"> Browse </button>

.ts

export class AppComponent {
  file: File;

  constructor() {

  }

  fileChange(file) {
    this.file = file.target.files[0];
    console.log(this.file.name);
  }
}
Dakota
  • 495
  • 2
  • 10
  • Thanks it works, I select a file then it gives me file name on console, I want to browse again but then click cancel then I get this error: "ERROR TypeError: Cannot read property 'name' of undefined " is there a way to prevent this? Also can I specify the browse location? – Anarkie Nov 16 '17 at 10:25
  • 1
    1. Cannot read property 'name' of undefined " => you need to check this.file != undefined 2. Can I specify the browse location? => no , y cant do it – Dakota Nov 17 '17 at 02:04
  • when I load the same image, nothing happens, any tips? here is my new question https://stackoverflow.com/questions/47473692/browse-the-same-file-again-and-again-in-html – Anarkie Nov 24 '17 at 12:50
1

You could try good old hidden input in label:

<label class="btn">
    Browse <input type="file" style="display: none;" (change)="handleChange($event)">
</label>

handleChange implementation would have to consume event:

handleChange(event) {
    // consume event.target.files[0] which has File type
}

rest about File can be found on MDN

gaa
  • 1,132
  • 11
  • 26
  • Im kind of getting closer to the solution, I altered the handleChange to `public handleChange(event: MouseEvent) { }` but my Browse button got bigger, inside the Browse button now there is a second button "Choose file" and label "No file chosen". Nothing happens when I click browse but when I click "Choose file" then I can select something. Of course I want only the Browse button to select file. – Anarkie Nov 15 '17 at 17:04
  • have you applied style `display: none` to `input`? – gaa Nov 15 '17 at 21:15
1

Because of browser security features, you're actually required to use the input tag to access the filesystem. What you can do, though, is hide the input element and access it from the rest of your code and markup.

Take a look at this related answer to get an idea of what you can do. Otherwise, here's a simple example of how it could work:

<input type="file" style="display: none" #file/>
<button type="button" class="btn" (click)="file.click()" Browse </button
BenWurth
  • 790
  • 1
  • 7
  • 23
  • `file.click()` lets me select a file but then where does this file go? How can I process the selected file or pass it to my own function `openPicture()` ? I want to process the selected file, show it on html and then save to db. – Anarkie Nov 15 '17 at 17:23