• 0
Votes
name

A PHP Error was encountered

Severity: Notice

Message: Undefined index: userid

Filename: views/question.php

Line Number: 195

Backtrace:

File: /home/u125378470/domains/lawhelpguru.org/public_html/application/views/question.php
Line: 195
Function: _error_handler

File: /home/u125378470/domains/lawhelpguru.org/public_html/application/controllers/Questions.php
Line: 416
Function: view

File: /home/u125378470/domains/lawhelpguru.org/public_html/index.php
Line: 315
Function: require_once

name Punditsdkoslkdosdkoskdo

How to create editFrom to edit Recipe in Angular

In my database i have many users which has many recipes. Every recipe has some properties and collection of ingredients. Below is screenshot

Recipe with all properties

I have created form for adding Recipe but i need to "change" it into edit.

So when user display recipe to edit on page should appear (form) recipe with loaded current data.

How i can reach it?

export class RecipeEditComponent implements OnInit {
  photos: IPhoto[] = [];
  uploader: FileUploader;
  hasBaseDropZoneOver = false;
  baseUrl = environment.apiUrl;
  currentMain: IPhoto;

  @Output() cancelRegister = new EventEmitter();
  recipeForm: FormGroup;
  ingredients: FormArray;
  categories: ICategory[];
  kitchenOrigins: IKitchenOrigin[];
  recipe: IRecipe;


  constructor(private route: ActivatedRoute, private recipeService: RecipeService,
    private toastr: ToastrService, private fb: FormBuilder) { }

  ngOnInit(): void {
    this.loadRecipe();   
    this.intitializeRecipeForm();
  }

  intitializeRecipeForm() {
    this.recipeForm = this.fb.group({
      name: ['', Validators.required],
      preparationTime: ['', Validators.required],
      description: ['', Validators.required],
      numberOfCalories: ['', Validators.required],
      categoryId: ['', Validators.required],
      kitchenOriginId: ['', Validators.required],
      ingredients: this.fb.array([this.createIngredient()])
    });
  }

  createIngredient(): FormGroup {
    return this.fb.group({
      name: ['', Validators.required],
      amount: ['', Validators.required],
    });
  }

  addIngredient(): void {
    this.ingredients = this.recipeForm.get('ingredients') as FormArray;
    this.ingredients.push(this.createIngredient());
  }

  removeIngredient(i:number) {
    this.ingredients.removeAt(i);
  }

  loadRecipe() {
    this.recipeService.getRecipe(this.route.snapshot.params.id).subscribe(recipe => {
      this.recipe = recipe;
      this.initializeUploader();
    })
  }

  public fileOverBase(e: any): void {
    this.hasBaseDropZoneOver = e;
  }

  initializeUploader () {
    this.uploader = new FileUploader({
      url: this.baseUrl + 'recipes/' + this.recipe.id + '/add-photo',
      authToken: 'Bearer ' + localStorage.getItem('token'),
      isHTML5: true,
      allowedFileType: ['image'],
      removeAfterUpload: true,
      autoUpload: false,
      maxFileSize: 10 * 1024 * 1024
    });
    this.uploader.onAfterAddingFile = (file) => {
      file.withCredentials = false;
    }

    this.uploader.onSuccessItem = (item, response, status, headers) => {
      if (response) {
        const photo : IPhoto = JSON.parse(response);
        this.recipe.recipePhotos.push(photo);
        if (photo.isMain) {
          this.recipe.photoUrl = photo.url;
        }
      }
    }
  }

  updateRecipe(id: number) {
    this.recipeService.editRecipe(id, this.recipe).subscribe(next => {
      this.toastr.success('Recipe updated successfully');
      this.recipeForm.reset(this.recipe);
    }, error => {
      this.toastr.error(error);
    });
  }

  setMainPhoto(photo: IPhoto) {
    this.recipeService.setMainPhoto(this.recipe.id, photo.id)
      .subscribe(() => {
        this.currentMain = this.recipe.recipePhotos.filter(p => p.isMain === true)[0];
        if (this.currentMain) {
          this.currentMain.isMain = false;
          photo.isMain = true;
          this.toastr.success('Succesfully changed main photo');
        }
      }, error => {
        this.toastr.error(error);
      });
  }

  deletePhoto(id: number) {

    this.recipeService.deletePhoto(this.recipe.id, id).subscribe(() => {
      this.recipe.recipePhotos.splice(this.recipe.recipePhotos.findIndex(p => p.id === id), 1);
      this.toastr.success('Photo has been deleted');
    }, error => {
      this.toastr.error('Failed to delete the photo');
    });
  }

  cancel() {
    this.cancelRegister.emit(false);
  }

}

Html

class="container mt-4 border" *ngIf="recipe"> <form [formGroup]='recipeForm' (ngSubmit)="recipeForm.valid && updateRecipe(recipe.id)" > <p class="h4 mb-4">Add new recipe</p> <app-text-input [formControl]='recipeForm.controls["name"]' [label]='"Name"' name="recipeForm.controls['name']"></app-text-input> <div class="form-group"> <app-editor-input [formControl]='recipeForm.controls["description"]' [label]='"Description"' name="description" ></app-editor-input> </div> <div formArrayName="ingredients"> <div *ngFor="let ingredient of recipeForm.get('ingredients')['controls']; let i = index;"> <div formGroupName={{i}} class="row"> <div class="form-group col-6"> <app-text-input formControlName="name" [label]='"Name"'></app-text-input> </div> <div class="form-group col-6"> <app-text-input formControlName="amount" [label]='"Amount"' [type]="'number'"></app-text-input> </div> </div> <button *ngIf="i" type="button" class="btn btn-sm btn-danger" (click)="removeIngredient(ingredient.id)" ><i class="fa fa-trash-o"></i></button> </div> </div> <button type="button" class="btn btn-primary" (click)="addIngredient()"> New Ingredient </button> <ng-container *ngFor="let ingredient of ingredients"> {{ingredient.name}} </ng-container> <div class="form-group text-center"> <button [disabled]="!recipeForm.valid" class="btn btn-outline-dark mr-2" type="submit">Add</button> <button class="btn outline-light mr-2" (click)="cancel()">Cancel</button> </div> </form> <h3 class="text-center">Photos</h3> <div class="row"> <div class="col-sm-2" *ngFor="let photo of recipe.recipePhotos"> <img src="{{photo.url}}" class="img-thumbnail p-1" alt=""> <div class="text-center"> <button type="button" class="btn btn-sm mr-1 mb-2" (click) = "setMainPhoto(photo)" [disabled]="photo.isMain" [ngClass] = "photo.isMain ? 'btn-danger active' : 'btn-secondary'" >Main</button> <button type="button" class="btn btn-sm btn-danger mb-2" (click)="deletePhoto(photo.id)" > <i class="fa fa-trash-o"></i></button> </div> </div> </div> <div class="row justify-content-md-center mt-5 border"> <div class="col col-sm-4"> <div class="mt-4 text-center"> Multiple <input type="file" ng2FileSelect [uploader]="uploader" multiple="true" /><br/> Single <input type="file" ng2FileSelect [uploader]="uploader" /> </div> </div> <div class="col col-sm-6"> <div ng2FileDrop [ngClass]="{'nv-file-over': hasBaseDropZoneOver}" (fileOver)="fileOverBase($event)" [uploader]="uploader" class="card bg-faded p-3 text-center mt-3 mb-3 my-drop-zone"> <i class="fa fa-upload fa-3x"></i> Drop Photos Here </div> </div> </div> <div class="col-md-6 mt-5" style="margin-bottom: 40px" *ngIf="uploader?.queue?.length"> <h3 class="text-center">Upload queue</h3> <p>Queue length: {{ uploader?.queue?.length }}</p> <table class="table"> <thead> <tr> <th width="50%">Name</th> <th>Size</th> </tr> </thead> <tbody> <tr *ngFor="let item of uploader.queue"> <td><strong>{{ item?.file?.name }}</strong></td> <td *ngIf="uploader.options.isHTML5" nowrap>{{ item?.file?.size/1024/1024 | number:'.2' }} MB</td> <td *ngIf="uploader.options.isHTML5"> </tr> </tbody> </table> <div> <div> Queue progress: <div class="progress mb-4" > <div class="progress-bar" role="progressbar" [ngStyle]="{ 'width': uploader.progress + '%' }"></div> </div> </div> <button type="button" class="btn btn-success btn-s" (click)="uploader.uploadAll()" [disabled]="!uploader.getNotUploadedItems().length"> <span class="fa fa-upload"></span> Upload </button> <button type="button" class="btn btn-warning btn-s" (click)="uploader.cancelAll()" [disabled]="!uploader.isUploading"> <span class="fa fa-ban"></span> Cancel </button> <button type="button" class="btn btn-danger btn-s" (click)="uploader.clearQueue()" [disabled]="!uploader.queue.length"> <span class="fa fa-trash"></span> Remove </button> </div> </div> <button form="recipeForm" class="btn btn-success btn-block mb-5 mt-5">Save changes</button> </div>

For now it's look like:

Form on page