1

I am making a form that sends information to a database in order to learn CRUD operation with Angular6 and Firebase, however when I submit it I get:

AddNewAnimalComponent.html:5 ERROR TypeError: Cannot read property 'push' of undefined
    at AnimalsService.push../src/app/animals.service.ts.AnimalsService.insertAnimal (animals.service.ts:32)
    at AddNewAnimalComponent.push../src/app/add-new-animal/add-new-animal.component.ts.AddNewAnimalComponent.onSubmit (add-new-animal.component.ts:24)
    at Object.eval [as handleEvent] (AddNewAnimalComponent.html:5)
    at handleEvent (core.js:23097)
    at callWithDebugContext (core.js:24167)
    at Object.debugHandleEvent [as handleEvent] (core.js:23894)
    at dispatchEvent (core.js:20546)
    at core.js:22036
    at SafeSubscriber.schedulerFn [as _next] (core.js:13517)
    at SafeSubscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.SafeSubscriber.__tryOrUnsub (Subscriber.js:196)

I debugged and went through my code line by line, but I still can't find why it is undefined, what am I doing wrong? Here is my form html:

<label>Last Fed</label>
    <input type="date" formControlName="lastFed" class="form-control">
    </div>
    <div class="form-group">
    <label>Last Shed</label>
    <input type="date" formControlName="lastShed" class="form-control">
    </div> <div class="form-group">
    <label>Diet</label>
    <input formControlName="diet" class="form-control" [ngClass]="{'is-invalid': submitted && formControl.animalName.errors}">
    <div class="invalid-feedback" *ngIf="submitted && formControl.animalName.errors">
      Each animal's diet must be known
     </div>
     </div>
     <div class="form-group">
     <label>Comments</label>
      <textarea formControlName="comments" class="form-control"> </textarea>
     </div>
     <div class="form-group">
    <input type="submit" class="btn btn-primary" value="Submit">
    </div>
    </form>
    <div class="alert alert-info" *ngIf="succesMessage">
      Submitted successfully.
    </div>
  </div>
</div>
</div>

my form ts:

import { Component, OnInit } from '@angular/core';
import { AnimalsService } from '../animals.service';

@Component({
  selector: 'app-add-new-animal',
  templateUrl: './add-new-animal.component.html',
  styleUrls: ['./add-new-animal.component.scss']
})
export class AddNewAnimalComponent implements OnInit {

  constructor(public animalsService: AnimalsService) { }
  submitted: boolean;
  succesMessage: boolean;
  formControl = this.animalsService.form.controls;

  ngOnInit() {

  }

  onSubmit() {
    this.submitted = true;
    if(this.animalsService.form.valid) {
      if(this.animalsService.form.get('$key').value == null)
      this.animalsService.insertAnimal(this.animalsService.form.value);
      this.succesMessage = true;
      setTimeout(() => this.succesMessage = false, 3000);
      this.submitted = false;
    }
  }
}

and my service that connects to firebase:

import { Injectable } from '@angular/core';
import { FormControl, FormGroup, Validators} from '@angular/forms';
import { AngularFireDatabase, AngularFireList } from 'angularfire2/database';

@Injectable({
  providedIn: 'root'
})

export class AnimalsService {

  constructor(public firebase: AngularFireDatabase) {}

  animalList: AngularFireList<any>

  form = new FormGroup({
    $key: new FormControl(null),
    animalName: new FormControl('', Validators.required),
    species: new FormControl('', Validators.required),
    age: new FormControl(''),
    lastFed: new FormControl(''),
    lastShed: new FormControl(''),
    diet: new FormControl('', Validators.required),
    comments: new FormControl('')
  });

  getAnimals() {
    this.animalList = this.firebase.list('animals');
    return this.animalList.snapshotChanges();
  }

  insertAnimal(animal) {
     this.animalList.push({
      animalName: animal.animalName,
      species: animal.species,
      age: animal.age,
      lastFed: animal.lastFed,
      lastShed: animal.lastShed,
      diet: animal.diet,
      comments: animal.comments
    });
  }
}
1
  • You never called getAnimals in your code, resulting in a variable that is undefined. Try calling it in your ngOnInit method of your component. Commented Mar 12, 2019 at 13:28

2 Answers 2

2

Your animalList in AnimalsService is null at the moment you want to push into that list. As far as I can see in your code, getAnimals() is never called, therefore that array is null.

You either put a call to getAnimals() to ngOnInit():

ngOnInit() {
  this.getAnimals();
}

or you can also add an empty AngularFireList when declaring the animalList or in the constructor.

Sign up to request clarification or add additional context in comments.

Comments

1

The local variable animalList is intitally undefined when you declare it like this.

animalList: AngularFireList<any>

Either assign it an initial value in the declaration like this

animalList: AngularFireList<any> = new AngularFireList()

or assign a value to the variable in the constructor

constructor(public firebase: AngularFireDatabase) {
  this.animalList = initialValue
}

or from your code you already have a getAnimals function, depending on the context use it either inside the constructor or call it after the component initialization (ngOnInit)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.