Angular Karma - TypeError:无法读取未定义的属性“_id”

Posted

技术标签:

【中文标题】Angular Karma - TypeError:无法读取未定义的属性“_id”【英文标题】:Angular Karma - TypeError: Cannot read property '_id' of undefined 【发布时间】:2020-11-22 02:49:05 【问题描述】:

当我尝试使用 karma jasmin 进行测试时,我收到了这个错误...

TypeError: Cannot read property '_id' of undefined

组件.ts

import  Component, OnInit  from '@angular/core';
import  ApiService  from '../../../services/api.service';
import  Router  from '@angular/router';
import  NgxSpinnerService  from "ngx-spinner";
import  ToasterConfig  from 'angular2-toaster';
import  NbComponentStatus, NbGlobalPhysicalPosition, NbToastrService  from '@nebular/theme';
import  ToastrService  from 'ngx-toastr';

@Component(
  selector: 'ngx-edit-subscription',
  templateUrl: './edit-subscription.component.html',
  styleUrls: ['./edit-subscription.component.scss']
)
export class EditSubscriptionComponent implements OnInit 

  title = [
    "name": "Name",
    "name": "Description", 
    "name": "Price", 
    "name": "Quantity", 
    "name": "Total"];
  
  review = false;
  recipientDetails:any;
  subtotal: number = 0;
  tax: number = 100.00;
  total: number = 0;
  orders: any = [];
  menuitems: any = [];
  selectedItems: any = [];
  recipientId:any;
  recipientAddressId:any;
  cartId:any;
  searchItem:string='';
  searchitemNumber="";
  searchDescription:string='';
  searchPrice:string='';
  imageShow: boolean = false;
  imageUrl: any = '';
  item: any = '';
  itemNumber= '';
  desc: any = '';
  price: any = '';
  vendorID: any;
  response: any;
  subscriptionItem : any;
  subscriptionItemsId : any;
  subscriptionItems_Id : any;
  cartDetails:any;

  constructor(private apiService: ApiService,
    private router: Router,
        private toastrService: ToastrService,
    private spinner: NgxSpinnerService)  
    this.recipientDetails = JSON.parse(localStorage.getItem('recipientDetails')) || ;
    localStorage.setItem('subId', this.recipientDetails._id);

    this.recipientId = this.recipientDetails.recipientId._id ? this.recipientDetails.recipientId._id : '';
    this.recipientAddressId = this.recipientDetails._id ? this.recipientDetails._id : '';
    this.vendorID = localStorage.getItem('vendorID');
    let zipCode = this.recipientDetails.zipCode;
    this.spinner.show();
    this.venueId = this.recipientDetails.deliveryAreaId[0].venueId;

     this.apiService.getMenubyCategory(this.vendorID).subscribe((res)=>
      this.spinner.hide();
      this.orders = res.body.vendorTags;
      for(let order of this.orders) 
        for(let prod of order.menudetails) 
          prod['quantity'] = 0;
        
      
      this.spinner.show();
     this.apiService.userSubscription(this.recipientDetails._id).subscribe((resp)=>
      this.spinner.hide();
      this.response = resp;
      this.subscriptionItem = this.response.subscriptionItem[0];
      this.subscriptionItemsId = this.subscriptionItem.subscriptionItemsId[0];
      this.subscriptionItems_Id = this.subscriptionItemsId._id;
      for(let menuItems of this.subscriptionItemsId.menuItems) 
        for(let order of this.orders) 
          for(let prod of order.menudetails) 
            if(prod._id === menuItems.menuItemId._id) 
              prod['quantity'] = menuItems.quantity;
            
          
        
      
     );
     );
  

  venueId:any;

  ngOnInit() 
    this.apiService.editSubscription = true;
  

  imagePopupShow(url: any) 
    var scrollElem= document.querySelector('#moveTop-row');
    scrollElem.scrollIntoView();
    this.imageShow = true;
    this.imageUrl = url;
  
  imagePopupHide() 
    this.imageShow = false;
    this.imageUrl = '';
  
  search(query, tab) 

    if(tab === 'item') 
      this.item = query;
    
    if(tab === 'itemNumber') 
      this.itemNumber = query;
    
    if(tab === 'description') 
      this.desc = query;
    
    if(tab === 'price') 
      this.price = query;
    
    var data2 = 
      "item" : this.item,
      "itemNumber" : this.itemNumber,
      "description" : this.desc,
      "price":this.price,
      "vendorId":this.vendorID
    ;
    this.spinner.show();
    this.apiService.searchOrder(data2).subscribe((res)=>
     this.spinner.hide();
     this.orders = res.body.vendorTags;
     for(let order of this.orders) 
       for(let prod of order.menudetails) 
         prod['quantity'] = 0;
       
     
     );

  
  reviewOrder() 
    this.menuitems = [];
    this.spinner.show();
      for(let order of this.orders) 
        for(let product of order.menudetails) 
          if(product.quantity > 0)
              this.menuitems.push(
                deliverRestOfOrder: true,
                menuItemId: 
                  _id: product._id,
                  name: product.name,
                  price: product.price
                ,
                quantity: product.quantity,
             );
          
        
      
      if(this.menuitems.length == 0)
        this.toastrService.error('', 'Please Select Atleast One menu');
        this.spinner.hide();
        return;
      
      var data2 = 
       "subscriptionItemId": this.subscriptionItems_Id,
       "menuItems": this.menuitems
     ;
      this.apiService.reviewSubscription(data2).subscribe((res)=>
        this.spinner.hide();
        this.toastrService.success('', 'Succesfully Added');
        this.cartDetails = res;
        localStorage.setItem('totalAmount',this.cartDetails.subscriptionItem[0].totalAmount);
        localStorage.setItem('typeOfSubscription', this.cartDetails.subscriptionItem[0].subscriptionId[0].typeOfSubscription);
        this.review = true;
      );
  

 

  addToCart(item) 
    if(item.quantity<0)
      item.quantity = 0;
    
    return;
    if(this.menuitems.length>0)
      var arr = this.menuitems;
      function userExists(menuItemId) 
        return arr.some(function(el) 
          return el.menuItemId === menuItemId;
        ); 
      
      var exists = userExists(item._id);
      if(exists == true)
        for(var i in this.menuitems)
          if(this.menuitems[i].menuItemId == item._id)
            this.menuitems[i].quantity = this.menuitems[i].quantity+1;
            break;  
          
        
       else 
        this.menuitems.push(menuItemId: item._id, quantity: 1, name: item.name, price:  item.price);
       
      var data = 
        "cartId" : this.cartId,
        "vendorId" : this.vendorID,
        "venueId" : this.venueId,
        "recipientId":this.recipientId,
        "recipientAddressId":this.recipientAddressId,
        "menuItems": this.menuitems
      ;
      this.apiService.updateCart(data).subscribe((res)=>
        
      );
     else 
      this.menuitems.push(menuItemId: item._id, quantity: 1, name: item.name, price:  item.price);
      var data2 = 
        "vendorId" : this.vendorID,
        "venueId" : this.venueId,
        "recipientId":this.recipientId,
        "recipientAddressId":this.recipientAddressId,
        "menuItems": this.menuitems
      ;
      this.apiService.addToCart(data2).subscribe((res)=>
        this.cartId = res.cartId;
      );
     
  



规格.ts

import  async, ComponentFixture, TestBed  from '@angular/core/testing';

import  EditSubscriptionComponent  from './edit-subscription.component';
import  NbCardModule  from '@nebular/theme';
import  FormsModule  from '@angular/forms';
import  DummyService  from '../../../services/dummy.service';
import  RouterTestingModule  from '@angular/router/testing';
import  ToastrService  from 'ngx-toastr';
import  HttpClientTestingModule  from '@angular/common/http/testing';

class MockDummyService extends DummyService 
  // mock everything used by the component
;

describe('EditSubscriptionComponent', () => 
  let component: EditSubscriptionComponent;
  let fixture: ComponentFixture<EditSubscriptionComponent>;

  beforeEach(async(() => 
    TestBed.configureTestingModule(
      imports: 
      [
        RouterTestingModule,
        NbCardModule,
        FormsModule,
        HttpClientTestingModule
      ],
      declarations: [ EditSubscriptionComponent ],
      providers: 
      [

        
          provide: ToastrService,
          useClass: MockDummyService
        ,
      ]
    )
    .compileComponents();
  ));

  beforeEach(() => 
    fixture = TestBed.createComponent(EditSubscriptionComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  );

  it('should create', () => 
    expect(component).toBeTruthy();
  );
);

谢谢.................................................. ..................................................... ..................................................... ..................................................... ....................

【问题讨论】:

【参考方案1】:

您正在检查本地存储中是否存在recipientDetails

this.recipientDetails = JSON.parse(localStorage.getItem('recipientDetails')) || ;

如果给定recipientDetails 中的_id 存在:

this.recipientId = this.recipientDetails.recipientId._id ? this.recipientDetails.recipientId._id : '';

但你订阅的是 userDetails 而不是this.recipientId

this.apiService.userSubscription(this.recipientDetails._id).subscribe((resp)=>

如果this.recipientDetails 将是,如第一行所示,使用this.recipientDetails._id 将引发错误"Cannot read property '_id' of undefined"

尝试向订阅发送this.recipientId,并处理后端缺少_id的可能性

【讨论】:

以上是关于Angular Karma - TypeError:无法读取未定义的属性“_id”的主要内容,如果未能解决你的问题,请参考以下文章

Angular Karma - TypeError:无法读取未定义的属性“_id”

Ionic3测试:TypeError:无法读取undefined的属性'subscribe'

TypeError:无法分配给只读属性 - Karma

使用 jasmine 和 karma 进行单元测试时形成数组错误

karma TypeError“无法读取未定义的属性'subscribe'”

在 Angular 8 (Karma 4.1.0) 升级后,在 Angular 7 (Karma 2.0.4) 中成功完成的 Karma 测试失败