Upload and show image in Angular

Viewed 72

I hope somebody can help me on this: For a private project I am using Angular 13 with php and mysql as the database. Now I was already able to make them all communicate with each other, which means I can upload recipe information to the database. How I fail when it comes to uploading a picture of the recipe. I know that there are 2 ways to do that: Upload the image in the database as a BLOB file or to just save the path of the image. I would prefer to 2nd way. I am able to display the image when the path is saved in the database but I cannot save it there (by letting the user select the image) and not me pasting it in manually.

I posted my code here as requested. Hope this helps. My question is still how to save the path of an image that the user selects into the database. Thanks for any adivse/help.

recipe-new.component.html

<div class="bg-success p-2 text-dark bg-opacity-10">
<br>
<div class="container">

<form #rezeptNeu="ngForm" (ngSubmit)="onSubmit()">

<button class="btn btn-primary" type="submit">Neues Rezept anlegen</button>
            <br><br>
            
<div class="row">
    <div class="col-4">
        <h2>Allgemeine Angaben</h2><br>
            <br>
            <div class="form-group">
                <label><p class="fw-bold">Name</p></label>
            <input type="text" name="name" class="form-control" placeholder="Name des Rezeptes." [(ngModel)]="rezeptesammlung.name">
            </div><br>
            <div class="form-group">
                <label><p class="fw-bold">Kurzbeschreibung</p></label>
            <input type="text" name="textkurz" class="form-control" placeholder="Hinweise zum Rezept." [(ngModel)]="rezeptesammlung.textkurz">
            </div><br>
            <div class="form-group">
                <label><p class="fw-bold">Zubereitungsdauer</p></label>
            <input type="text" name="dauer" class="form-control" placeholder="Kochzeit (ohne Backen), zb 30." [(ngModel)]="rezeptesammlung.dauer">
            </div><br>
            <div class="form-group">
                <label><p class="fw-bold">Schwierigkeitsgrad</p></label>
                <select class="form-select" id="inputGroupSelect01" name="schwierigkeitsgrad" [(ngModel)]="rezeptesammlung.schwierigkeitsgrad">
                    <option selected>Bitte auswählen...</option>
                    <option value="http://localhost/kochen/uploads/schwierigkeit/hauben1.png">leicht</option>
                    <option value="http://localhost/kochen/uploads/schwierigkeit/hauben2.png">mittel</option>
                    <option value="http://localhost/kochen/uploads/schwierigkeit/hauben3.png">schwer</option>
                </select>
            </div><br>
            <div class="form-group">
                <label><p class="fw-bold">Kategorie</p></label>
                <select class="form-select" name="category" [(ngModel)]="rezeptesammlung.category">
                    <option selected>Bitte auswählen...</option>
                    <option value="http://localhost/kochen/uploads/birnenkuchen.jpg">Frühstück</option>
                    <option value="http://localhost/kochen/uploads/gurkensalat.jpg">Mittagessen</option>
                    <option value="http://localhost/kochen/uploads/gurkensalat.jpg">Abendessen</option>
                    <option value="http://localhost/kochen/uploads/gurkensalat.jpg">Nachspeise</option>
                    <option value="http://localhost/kochen/uploads/gurkensalat.jpg">Sonstiges</option>
                </select>
             </div><br>
             <div class="form-group">
                <label><p class="fw-bold">Rating</p></label>
                <select class="form-select" name="rating" [(ngModel)]="rezeptesammlung.rating">
                    <option selected>Bitte auswählen...</option>
                    <option value="http://localhost/kochen/uploads/rating/stern_1.png">1 Stern</option>
                    <option value="http://localhost/kochen/uploads/rating/stern_2.png">2 Sterne</option>
                    <option value="http://localhost/kochen/uploads/rating/stern_3.png">3 Sterne</option>
                    <option value="http://localhost/kochen/uploads/rating/stern_4.png">4 Sterne</option>
                    <option value="http://localhost/kochen/uploads/rating/stern_5.png">5 Sterne</option>
                </select>
             </div><br>

           <div class="form-group">
                <label><p class="fw-bold">Image</p></label>
            <input type="file" name="image" class="form-control" [(ngModel)]="rezeptesammlung.image">
            </div><br>
            
    </div>

    <!--für Abstand-->
    <div class="col-1">
        </div>

    <div class="col-7">
        <h2>Zubereitungsschritte und Zutaten</h2><br>
        <div class="row">
            <div class="col-8">
                <div class="form-group">
                    <br>  
                    <label><p class="fw-bold">Schritt 1</p></label><br>
                <textarea name="zubereitung_1" class="form-control" rows="5" [(ngModel)]="rezeptesammlung.zubereitung_1"></textarea>
                </div>
            </div>
            <div class="col-8">
                <div class="form-group">
                    <br>
                    <label><p class="fw-bold">Schritt 2</p></label><br>
                <textarea name="zubereitung_2" class="form-control" rows="5" [(ngModel)]="rezeptesammlung.zubereitung_2"></textarea>
                </div>
            </div>
            <div class="col-8">
                <div class="form-group">
                    <br>
                    <label><p class="fw-bold">Schritt 3</p></label><br>
                <textarea name="zubereitung_3" class="form-control" rows="5" [(ngModel)]="rezeptesammlung.zubereitung_3"></textarea>
                </div><br>
            </div>
        </div>
    
        <!--für Abstand-->
        <div class="col-1"> </div>

        <div class="col-8">
           <!-- <h2>Zutaten</h2><br>-->
            <div class="row">
            <div class="form-group">
                <br>
                <label><p class="fw-bold">Zutaten</p></label><br>
            <textarea name="zutaten" class="form-control" rows="5" [(ngModel)]="rezeptesammlung.zutaten"></textarea>
            </div>
            </div>    
        </div>
       </div>

    </div>
   
</form>

</div>

Rezept-neu.component.html

import { Component } from '@angular/core';
import { RezepteService } from '../rezepte.service';
import { RezepteSammlung } from '../rezepte-sammlung';

@Component({
  selector: 'app-rezept-neu',
  templateUrl: './rezept-neu.component.html',
  styleUrls: ['./rezept-neu.component.css']
})
export class RezeptNeuComponent {

  rezeptesammlung = new RezepteSammlung('', '', '', '', '', '', '', '', '', '', '', '', '');

  constructor(private Rezept: RezepteService) { }

  onSubmit() {
   this.Rezept.make(this.rezeptesammlung).subscribe(rezepte => console.log('Erfolgreich gepspeichert', rezepte));

  }

}

recipe.service.ts

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { RezepteSammlung } from './rezepte-sammlung';
import { Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class RezepteService {
  //REST-API
  private api1 = 'http://localhost/kochen/angular1.php';
  private api2 = 'http://localhost/kochen/angular2.php';

  constructor(private http: HttpClient) { }

  //get-Methode, damit werden die Daten vom Server ausgelesen
  loadRezepte(): Observable<RezepteSammlung[]> {
    return this.http.get<RezepteSammlung[]>(this.api1);
  }
  //Damit sendet man die Daten zum Server.
  make(rezepte: RezepteSammlung) {
    console.log(rezepte);
    return this.http.post<any>(this.api2, rezepte);
  }

}

php

<?php
$con = new MySQLi("localhost", "root", "", "kochen");

if ($con->connect_error) {
    echo "Fehler bei der Verbindung: " . mysqli_connect_error();
    exit();
    }

if (!$con->set_charset("utf8")){
echo "Fehler bei utf8" . $con->error;
}

$essen = [];
$sql = "SELECT * FROM rezepte";
$result = mysqli_query($con, $sql);
$nr = 0; //damit er weiterzählt
while($row = mysqli_fetch_assoc($result))

{
    $essen[$nr]['rezeptid'] = $row['rezeptid'];
    $essen[$nr]['name'] = $row['name'];
    $essen[$nr]['textkurz'] = $row['textkurz'];
    $essen[$nr]['dauer'] = $row['dauer'];
    $essen[$nr]['schwierigkeitsgrad'] = $row['schwierigkeitsgrad'];
    $essen[$nr]['speicherung'] = $row['speicherung'];
    $essen[$nr]['category'] = $row['category'];
    $essen[$nr]['zubereitung_1'] = $row['zubereitung_1'];
    $essen[$nr]['zubereitung_2'] = $row['zubereitung_2'];
    $essen[$nr]['zubereitung_3'] = $row['zubereitung_3'];
    $essen[$nr]['rating'] = $row['rating'];
    $essen[$nr]['zutaten'] = $row['zutaten'];
    $essen[$nr]['image'] = $row['image'];
    $nr++;
}


echo json_encode($essen);
?>

Here is the api2 - php file:

<?php

$connect = new MySQLi("localhost", "root", "", "kochen");

//Get the data
$postdata = file_get_contents("php://input");

//Extract the data
$request = json_decode($postdata);

//Entfernung von Zeichen, die beim SQL-Befehl problematisch sein könnten
$name = mysqli_real_escape_string($connect, ($request->name));
$textkurz = mysqli_real_escape_string($connect, ($request->textkurz));
$dauer = mysqli_real_escape_string($connect, ($request->dauer));
$schwierigkeitsgrad = mysqli_real_escape_string($connect, ($request->schwierigkeitsgrad));
$category = mysqli_real_escape_string($connect, ($request->category));
$zubereitung_1 = mysqli_real_escape_string($connect, ($request->zubereitung_1));
$zubereitung_2 = mysqli_real_escape_string($connect, ($request->zubereitung_2));
$zubereitung_3 = mysqli_real_escape_string($connect, ($request->zubereitung_3));
$rating = mysqli_real_escape_string($connect, ($request->rating));
$zutaten = mysqli_real_escape_string($connect, ($request->zutaten));
$image = mysqli_real_escape_string($connect, ($request->image));

$sql = "INSERT INTO rezepte (name, textkurz, dauer, schwierigkeitsgrad, category, zubereitung_1, zubereitung_2, zubereitung_3, rating, zutaten, image)
VALUES ('{$name}', '{$textkurz}', '{$dauer}', '{$schwierigkeitsgrad}', '{$category}', '{$zubereitung_1}', '{$zubereitung_2}', '{$zubereitung_3}', '{$rating}', '{$zutaten}', '{$image}');";

mysqli_query($connect, $sql);

?>
1 Answers

If it's just for a local experiment then you could try store the images in the assets folder of your angular project and then reference them in your component. In that way you can still select them in your frontend, however this will not allow you to add images after you have deployed your app on a server. Then the only way is to upload images and store them (either in a database or blob storage or server folder where you have access)

Related