错误TypeError:无法读取Object.eval上未定义的属性'temp'[作为updateRenderer](SearchCitiesComponent.html:21)

时间:2020-04-11 07:32:55

标签: angular typescript

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { FlexLayoutModule } from '@angular/flex-layout';
import { MatToolbarModule } from '@angular/material/toolbar';
import { MatIconModule } from '@angular/material/icon';
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
import { MatButtonModule } from '@angular/material/button';
import { MatCardModule } from '@angular/material/card';
import { MatGridListModule } from '@angular/material/grid-list';
import { RouterModule, Routes } from '@angular/router';
import { MatInputModule } from '@angular/material/input';
import { MatSelectModule } from '@angular/material/select';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatListModule } from '@angular/material/list';
import { FormsModule } from '@angular/forms';
import { HttpClientModule } from '@angular/common/http';
import { AppComponent } from './app.component';
import { AngularFireModule } from 'angularfire2';
import { AngularFireDatabaseModule } from 'angularfire2/database';


import 'hammerjs';
import { HeaderComponent } from './header/header.component';
import { MatSidenavModule } from '@angular/material/sidenav';
import { SearchCitiesComponent } from './search-cities/search-cities.component';
import { AppRoutingModule } from './app-routing/app-routing.module';
import { AddcityComponent } from './addcity/addcity.component';
import { DetailsComponent } from './details/details.component';

import { environment } from 'src/environments/environment';
@NgModule({
  declarations: [
    AppComponent,
    HeaderComponent,
    SearchCitiesComponent,
    AddcityComponent,
    DetailsComponent
  ],
  imports: [
    BrowserModule,
    BrowserAnimationsModule,
    MatToolbarModule,
    FlexLayoutModule,
    MatIconModule,
    MatSlideToggleModule,
    MatSidenavModule,
    MatButtonModule,
    MatCardModule,
    MatGridListModule,
    RouterModule,
    MatInputModule,
    MatSelectModule,
    MatFormFieldModule,
    MatListModule,
    FormsModule,
    HttpClientModule,
    AppRoutingModule,
    AngularFireModule.initializeApp(environment.firebase),
    AngularFireDatabaseModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

searchCities.component.html

<mat-card class="search_cities">
    <mat-card-header>
        <mat-card-title class="card_title">SEARCH CITIES</mat-card-title>

    </mat-card-header>

    <input placeholder="SEARCH CITY" type="text" class="text_box" list="search" autocomplete=“off” [(ngModel)]="name">
    <button mat-icon-button class="search_button" (click)="searchCity()"><i class="fa fa-search fa-2x"></i></button>

    <datalist id="search" style="background-color: red;color: silver;">
                  <option value="London"></option>
                  <option value="big"></option>

              </datalist>
    <mat-card-content>
        <div style="padding-left: 40px;padding-top: 50px;">
        <mat-card style="height: 400px; width: 300px;">
            <div class="title">
                    {{name | uppercase}}
            </div>   
            <mat-card-content class="temp">
                {{temp['temp']- 273.15 | number:'1.0-0'}}&#8451;
            </mat-card-content>
            <div>
                <p class="main">
                    {{cities[0].main | uppercase}}
                </p>
                <p class="temp_min">
                    {{temp['temp_min']- 273.15 | number:'1.0-0'}}&#8451; &nbsp; &nbsp;<span class="temp_max">{{temp['temp_max']- 273.15 | number:'1.0-0'}}&#8451;</span>
                </p>
            </div>
            <div style="text-align: center;padding-top: 35px;">
            <button mat-raised-button (click)="add()" class="button"><span style="font-size: 25px;">&nbsp;&nbsp;&nbsp;&nbsp;ADD+&nbsp;&nbsp;&nbsp;&nbsp;</span></button>
            </div>
        </mat-card>
        </div>


    </mat-card-content>

</mat-card>

searchCities.component.ts

import { Component, OnInit } from '@angular/core';
import { WeatherService } from '../services/weather.service';
import { FirebaseService } from '../services/firebase.service';
import { AngularFireDatabase } from 'angularfire2/database';

import { from } from 'rxjs';

@Component({
  selector: 'app-search-cities',
  templateUrl: './search-cities.component.html',
  styleUrls: ['./search-cities.component.scss']
})
export class SearchCitiesComponent implements OnInit {

  constructor(private weathersService: WeatherService,
    private firebaseService: FirebaseService , private db: AngularFireDatabase ) { }
  cities: Array<any>;
  temp : Array<any>;
  name='';
  check: Array<any>;

  ngOnInit() {
  }

  searchCity(){
    this.weathersService.getcities(this.name).subscribe(data => this.temp = data['main']);
    this.weathersService.getcities(this.name).subscribe(data => this.cities = data['weather']);
  }

  add()
  {
    this. db.list('/user/cities').valueChanges().subscribe(check => {this.check = check});
    for (let c of this.check){
     if( c.name == this.name)
     {
      console.log("Please enter new city");
      return;
     }
    } 
      this.firebaseService.addCity(this.name , this.temp['temp'] , this.cities[0].main , this.temp['temp_min'] , this.temp['temp_max']);
  }
}

weather.service.ts

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Injectable({
  providedIn: 'root'
})
export class WeatherService {

key = "5b2329ae6d45a6392cb78ad20970331f";


  constructor(private http : HttpClient) { }

  getcities(city: string){
    return this.http.get('https://api.openweathermap.org/data/2.5/weather?q='+city+'&appid='+this.key);
  }

}

我的控制台中不断出现此错误。 “错误TypeError:无法读取未定义的属性'temp' 在Object.eval [作为updateRenderer](SearchCitiesComponent.html:21) 在Object.debugUpdateRenderer上[作为updateRenderer](core.js:11080)”。 请任何人帮助。尽我所能尝试。

2 个答案:

答案 0 :(得分:0)

我在这里看到多个问题。

  1. 您不必订阅两次即可获取数据。它将触发两个单独的HTTP请求。你可以做
searchCity() {
  this.weathersService.getcities(this.name).subscribe(
    data => { 
      this.temp = data['main'];
      this.cities = data['weather'];
    },
    error => {
      // handle error
    }
  );
}
  1. API的属性mainweather是对象。但是它们被声明为数组。您可以简单地将它们声明为any
  2. 类型
cities: any;
temp : any;
check: any;

答案 1 :(得分:0)

该错误与您的temp : Array<any>;变量有关,该变量在启动组件时未定义。

仅在您的getcities()可观察值返回值之后填充。除非用户按事物外观单击搜索按钮,否则这种情况不会发生。

要解决此问题,您可以隐藏使用temp['XXX']的元素,直到填充此变量为止。这样,Angular将不会尝试访问未定义变量的这些属性。例如;

...
<!-- if temp is defined, show -->
<mat-card style="height: 400px; width: 300px;" *ngIf="temp">
...
    <mat-card-content class="temp">
        {{temp['temp']- 273.15 | number:'1.0-0'}}&#8451; <!-- This will now be defined -->
    </mat-card-content>
...