ERROR TypeError: Cannot read properties of undefined (reading 'quantity') - Angular 12 - undefined

I have been facing this problem for quite some time now. When I try to add an item to my cart I get this error : ERROR TypeError: Cannot read properties of undefined (reading 'quantity').
Here is my cart service:
import { Injectable } from '#angular/core';
import { environment } from 'src/environments/environment';
import { Cart } from '../models/cart';
import { Item } from '../models/item';
import {Product} from '../models/product';
import {Subject} from 'rxjs';
#Injectable({
providedIn: 'root'
})
export class CartService {
cart:Cart=new Cart();
tva=environment.tva/100;
cart$=new Subject<Cart>();
constructor() { }
emitCart(){
this.cart$.next(this.cart)
}
addToCart(product:Product){
const item=this.cart.items.find(item=>item.product._id === product._id);
if(item){
item.quantity++;
}else{
const item=new Item();
item.product=product;
item.quantity=1;
this.cart.items.push(item);
}
this.updateCart();
}
updateCart(){
this.cart.items.forEach(item=>{
this.cart.resume.quantity+=item.quantity;
this.cart.resume.costHT+=item.quantity*item.product.price;
this.cart.resume.costTaxe+=this.cart.resume.costHT*this.tva;
this.cart.resume.costTTC+=this.cart.resume.costHT*(1+this.tva);
})
this.emitCart();
}
removeOne(product:Product){
}
removeMany(product:Product){
}
}
This is my header where a number should be added next to the shopping bag icon when I click on the add to cart icon :
This is my header component logic :
import { Component, OnInit } from '#angular/core';
import {AuthService} from "../../../services/auth.service";
import {CartService} from '../../../services/cart.service';
import {Cart} from '../../../models/cart';
#Component({
selector: 'node-header',
templateUrl: './header.component.html',
styleUrls: ['./header.component.css']
})
export class HeaderComponent implements OnInit {
isAuth;
resume:{quantity:number,costHT:number, costTaxe,costTTC:number};
constructor(private authService:AuthService,private cartService:CartService) { }
ngOnInit(): void {
this.cartService.cart$.subscribe(
(cart:Cart)=>{
this.resume=cart.resume;
console.log(cart.resume);
},
(err)=>{
console.log(err.message);
}
)
this.authService.isAuth$.subscribe(
(bool:boolean)=>{
this.isAuth=bool
}
)
}
logout(){
this.authService.logout();
}
}
And finally this is the html template of the header just in case :
<!-- header start -->
<header>
<!-- header top start -->
<div class="header-top theme1 bg-dark py-15">
<div class="container">
<div class="row align-items-center">
<div class="col-lg-6 col-md-7 order-last order-md-first">
<div class="static-info text-center text-md-left">
<p class="text-white">Join our showroom and get <span class="theme-color">10 % off</span> ! Coupon code : <span class="theme-color">Jstore2021</span></p>
</div>
</div>
<div class="col-lg-6 col-md-5">
<nav class="navbar-top pb-2 pb-md-0 position-relative">
<ul class="d-flex justify-content-center justify-content-md-end align-items-center">
<li>
Setting <i class="ion ion-ios-arrow-down"></i>
<ul class="topnav-submenu dropdown-menu" aria-labelledby="dropdown1">
<li>My account</li>
<li>Checkout</li>
<li>Sign out</li>
</ul>
</li>
<li>
USD $ <i class="ion ion-ios-arrow-down"></i>
</li>
<li class="english">
<a href="#" id="dropdown3" class="pr-0" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<img src="assets/img/logo/us-flag.jpg" alt="us flag"> English
<i class="ion ion-ios-arrow-down"></i>
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
</div>
<!-- header top end -->
<!-- header-middle satrt -->
<div class="header-middle pt-20">
<div class="container">
<div class="row align-items-center">
<div class="col-sm-6 col-lg-2 order-first">
<div class="logo text-center text-sm-left mb-30 mb-sm-0">
<img src="assets/img/logo/logo-dark.jpg" alt="logo">
</div>
</div>
<div class="col-sm-6 col-lg-5 col-xl-4">
<!-- search-form end -->
<div class="d-flex align-items-center justify-content-center justify-content-sm-end">
<div class="media static-media mr-50 d-none d-lg-flex">
<img class="mr-3 align-self-center" src="assets/img/icon/1.png" alt="icon">
<div class="media-body">
<div class="phone">
<span class="text-muted">Call us:</span>
</div>
<div class="phone">
(+33)752152560
</div>
</div>
</div>
<!-- static-media end -->
<div class="cart-block-links theme1">
<ul class="d-flex">
<li class="mr-0 cart-block position-relative" >
<a class="offcanvas-toggle" routerLink="/cart">
<span class="position-relative">
<i class="icon-bag"></i>
<span class="badge cbdg1" *ngIf="resume">{{resume.quantity}}</span>
</span>
<span class="cart-total position-relative" *ngIf="resume">{{resume.costTTC/100|currency:'EUR'}}</span>
</a>
</li>
<!-- cart block end -->
</ul>
</div>
<div class="mobile-menu-toggle theme1 d-lg-none">
<a href="#offcanvas-mobile-menu" class="offcanvas-toggle">
<svg viewbox="0 0 800 600">
<path
d="M300,220 C300,220 520,220 540,220 C740,220 640,540 520,420 C440,340 300,200 300,200"
id="top"></path>
<path d="M300,320 L540,320" id="middle"></path>
<path
d="M300,210 C300,210 520,210 540,210 C740,210 640,530 520,410 C440,330 300,190 300,190"
id="bottom" transform="translate(480, 320) scale(1, -1) translate(-480, -318)">
</path>
</svg>
</a>
</div>
</div>
</div>
<div class="col-lg-5 col-xl-6 order-lg-first">
<div class="search-form pt-30 pt-lg-0">
</div>
</div>
</div>
</div>
</div>
<!-- header-middle end -->
<!-- header bottom start -->
<!-- header bottom start -->
<nav class="header-bottom theme1 d-none d-lg-block">
<div class="container">
<div class="row align-items-center">
<div class="col-lg-10 offset-lg-2 d-flex flex-wrap align-items-center position-relative">
<ul class="main-menu d-flex">
<li routerLinkActive="active"><a routerLink="/">Home</a></li>
<li routerLinkActive="active"><a routerLink="/shop">Shop</a></li>
<li routerLinkActive="active"><a routerLink="/add-product">Add product</a></li>
<li routerLinkActive="active" ><a routerLink="/signin" *ngIf="!isAuth">Login</a></li>
<li routerLinkActive="active" ><a routerLink="/signup" *ngIf="!isAuth">Register</a></li>
<li routerLinkActive="active" style="color: black;cursor: pointer;" *ngIf="isAuth" (click)="logout()"><a >Logout</a></li>
</ul>
</div>
</div>
</div>
</nav>
<!-- header bottom end -->
</header>
Sorry I forgot to post the cart class and template so here they are :
import {Item} from '../models/item';
export class Cart {
items:Item[]=[];
resume:{quantity:number,costHT:number, costTaxe:number,costTTC:number};
}
And the item class :
import { Product } from "./product";
export class Item {
product:Product;
quantity:number;
}

All I needed to do was add this line as the first line of the updateCart() function:
resume={quantity=0,costHT=0, costTaxe=0,costTTC=0};

Related

How can i put the <hr> closer with the content in header?

I want to put the <hr closer to the content in the header.
I try to use position-absolute but the disappears.
This is my first project with bootstrap.
<!-- Bootstrap-5 -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<!--Body -->
<header class="header row">
<div class="d-flex justify-content-between">
<div id="logo" class="pb-2 ps-2 pe-0 col-2">
<img class="float-start py-2 ps-2 pe-2" src="assets/img/unknown.png">
<a href="#" class="sidebar-toggler flex-shrink-0" id="menu-toggle">
<i class="fa-solid fa-angle-left py-4 pe-2"></i>
</a>
</div>
<div class="col-10 row">
<h2 class="col-9 px-0 text-primary d-flex align-items-center">CHƯƠNG TRÌNH REBATE</h2>
<div class="col-3 px-0">
<div class="float-end d-flex justify-content-between">
<i class="fa fa-bell me-lg-2 d-flex align-items-center"></i>
<div class="nav-item dropdown">
<a href="#" class="nav-link dropdown-toggle" data-bs-toggle="dropdown">
<img class="rounded-circle " src="assets/img/aTu.png" alt="" style="width: 40px; height: 40px;">
<span class="d-none d-lg-inline-flex text-primary">TuNTC23</span>
</a>
<div class="dropdown-menu bg-transparent border-0">
My Profile
Settings
Log Out
</div>
</div>
</div>
</div>
</div>
</div>
<hr style="height:1px;color:#1968B2;">
</header>
<hr style="height:1px;color:#1968B2; margin-top: -4px">
you can adjust the margin top according to your usage
I suggest you do not use the <hr> tag but a new css class or ::after to do that.
<header class="header row hr-bottom">
.hr-bottom {
border-bottom: 1px solid black;
}
OR
.hr-bottom::after {
border-bottom: 1px solid black;
}
The fastest way add class to hr for example bar
<hr class="bar" style="height:1px;color:#1968B2;">
and in CSS add class:
.bar {
transform: translateY(-10px);
}
Values up to you It may take px or procentage

Overlap div with sidebar without move div elements/div position

I try to develop a sidebar that opens on hover.
My problem is that when the sidebar is opened, the div with the content changes its position.
Is there any way to open and close the sidebar and keep the same placement of the text div?
DEMO
HTML
<div class="row rowSide" id="body-row">
<div [ngClass]="{'mySideBar': isSidebarCollapsed == false, 'mySideBar1': isSidebarCollapsed == true}"
(mouseenter)="hover()" (mouseleave)="hover1()" id="sidebar-container" class="sidebar-expanded d-md-block">
<ul class="list-group">
<a href="#" class="bg-dark list-group-item list-group-item-action">
<div class="d-flex w-100 justify-content-start align-items-center">
<span class="fa fa-tasks fa-fw mr-3"></span>
<span *ngIf="isSidebarCollapsed == false" class="menu-collapsed">Tasks</span>
</div>
</a>
<a href="#" class="bg-dark list-group-item list-group-item-action">
<div class="d-flex w-100 justify-content-start align-items-center">
<span class="fa fa-calendar fa-fw mr-3"></span>
<span *ngIf="isSidebarCollapsed == false" class="menu-collapsed textCollapsed">Calendar</span>
</div>
</a>
<a href="#top" data-toggle="sidebar-colapse" (click)="collapseSidebar()"
class="bg-dark list-group-item list-group-item-action d-flex align-items-center">
<div class="d-flex w-100 justify-content-start align-items-center">
<span id="collapse-icon" class="fa fa-2x mr-3"></span>
<span *ngIf="isSidebarCollapsed == false" id="collapse-text" class="menu-collapsed textCollapsed">Collapse</span>
</div>
</a>
</ul><!-- List Group END-->
</div><!-- sidebar-container END -->
<!-- MAIN -->
<div class="col p-4">
<h1 class="display-4">Collapsing Sidebar Menu</h1>
<div class="card">
<h5 class="card-header font-weight-light">Requirements</h5>
<div class="card-body">
<ul>
<li>JQuery</li>
<li>Bootstrap 4.3</li>
<li>FontAwesome</li>
</ul>
</div>
</div>
</div><!-- Main Col END -->
</div><!-- body-row END -->
.TS
public isSidebarCollapsed;
constructor() {
this.isSidebarCollapsed = false;
}
public collapseSidebar() {
this.isSidebarCollapsed = true;
}
hover(){
this.isSidebarCollapsed = false;
}
hover1(){
this.isSidebarCollapsed = true;
}
Problem: When the sidebar is open, the text div must maintain the same placement as when the sidebar is closed.
You probably don't need to change position prop of sidebar. Make it always fixed and move your content div with margin like this:
#body-row {
margin-left:60px;
margin-right:0;
}
#sidebar-container {
position: fixed;
left: 0;
min-height: 100vh;
background-color: #333;
padding: 0;
}

Navbar Mobile view Links to pages not working

Navbar Mobile View I'm not sure if i deleted code but i cant seem to figure out why my links to pages aren't working (i know basic coding so please be kind :D) (also added screenshot of what it looks like, so the links work on the desktop view but nothing happens on mobile view upon clicking)
My code for the navbar:
<div class="site-mobile-menu site-navbar-target">
<div class="site-mobile-menu-header">
<div class="website-mobile-menu-close mt-3">
<span class="icon-close2 js-menu-toggle"></span>
</div>
</div>
<div class="site-mobile-menu-body"></div>
</div>
<header class="site-navbar py-4 js-sticky-header site-navbar-target" role="banner">
<div class="container2">
<div class="row align-items-center">
<div class="col-5 col-xl-2">
<h1 class="h2 site-header-logo">
<a href="Index.html" class="site-header-logo-image">
<imgsrc="images/Logo10Jul.png">
</a>
</h1>
</div>
<div class="col-12 col-md-10 d-none d-xl-block">
<nav class="navbar-nav site-navigation position-relative text-right"
role="navigation">
<ul class="site-menu main-menu js-clone-nav mr-auto d-none d-lg-block">
<li>Home</li>
<li>About Us</li>
<li>Felt Creations</li>
<li>Soothers</li>
<li>How to Order</li>
<li>Contact</li>
</ul>
</nav>
</div>
<div class="col-6 d-inline-block d-xl-none ml-md-0 py-3" style="position: relative;
top:3px;">
<a href="#" class="site-menu-toggle js-menu-toggle text-black float-right">
<span class="icon-menu h3"></span>
</a>
</div>
</div>
</div>
</header>

How to insert array object property value into HTML?

I wanted to make a simple carousel using DOM manipulation, I don't know if I can do this or not in Angular, but the idea is I created an array of objects with properties that I want to pass to the HTML using interpolation, and I don't know how to do it yet. Here's my code:
<div class="container">
<div class="row">
<div class="col-12 text-center">
<h1 class="mt-5 mb-1"><strong>carousel</strong></h1>
<div class="container">
<div class="row">
<div class="col-12">
<div class="carousel-container">
<div class="carousel-cell">
<div class="row text-center">
<div class="col-12">
<div class="row carousel-control">
<div class="col-2 carousel-prev fa-2x" (click)="carouselPrev()">
<fa-icon [icon]="faChevronLeft" class="mr-2"></fa-icon>
</div>
<div class="col-7 col-md-2">
<div class="carousel-image">
<img [src]="carousel.image" alt="carousel image">
</div>
</div>
<div class="col-2 carousel-next fa-2x" (click)="carouselNext()">
<fa-icon [icon]="faChevronRight" class="mr-2"></fa-icon>
</div>
</div>
</div>
<div class="col-12">
<div class="carousel-text mt-4">
<h3>{{carousel.description}}</h3>
<p><em> {{carousel.name}}, <span>{{carousel.affiliation}}</span></em></p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
import { Component } from '#angular/core';
import { Router } from '#angular/router';
import {faChevronLeft, faChevronRight, IconDefinition} from '#fortawesome/free-solid-svg-icons';
#Component({
selector: 'app-carousel',
templateUrl: './carousel.component.html',
styleUrls: ['./carousel.component.scss']
})
export class CarouselComponent implements OnInit {
faChevronLeft: IconDefinition = faChevronLeft;
faChevronRight: IconDefinition = faChevronRight;
carousel = [
{
id: 1,
name: 'captain america',
affiliation: 'camp lehigh',
description: 'language!',
image: 'http://picsum.photos/200'
},
{
id: 2,
name: 'thor',
affiliation: 'asgard',
description: 'i am god of thunder!',
image: 'http://picsum.photos/200'
},
{
id: 3,
name: 'tony stark',
affiliation: 'stark industries',
description: 'and i....am..iron man!',
image: 'http://picsum.photos/200'
}
];
constructor(
) {}
ngOnInit() {
}
carouselPrev() {
// i want to make this a control by making the id/index +1
}
carouselNext() {
// i want to make this a control by making the id/index -1
}
}
You can achieve it using ngFor with index.
Live example: https://stackblitz.com/edit/angular-b5qvwy
Some code:
Basic HTML
<h1>{{list[i].name}}</h1>
<div (click)="prev()"><</div>
<div (click)="next()">></div>
Basic TS code
export class AppComponent {
list = [
{
name: "Jhon"
},
{
name: "Joe"
},
{
name: "Marth"
}
];
i = 0;
prev(){
if(this.i > 0){
this.i--;
}
}
next(){
if(this.i < this.list.length -1){
this.i++;
}
}
}
For your example, simply do that in the html:
<div class="container">
<div class="row">
<div class="col-12 text-center">
<h1 class="mt-5 mb-1"><strong>carousel</strong></h1>
<div class="container">
<div class="row">
<div class="col-12">
<div class="carousel-container">
<div class="carousel-cell" *ngIf="carousel[i].id">
<div class="row text-center">
<div class="col-12">
<div class="row carousel-control">
<div class="col-2 carousel-prev fa-2x" (click)="carouselPrev()">
<fa-icon [icon]="faChevronLeft" class="mr-2"></fa-icon>
</div>
<div class="col-7 col-md-2">
<div class="carousel-image">
<img [src]="carousel[i].image" alt="carousel image">
</div>
</div>
<div class="col-2 carousel-next fa-2x" (click)="carouselNext()">
<fa-icon [icon]="faChevronRight" class="mr-2"></fa-icon>
</div>
</div>
</div>
<div class="col-12">
<div class="carousel-text mt-4">
<h3>{{carousel[i].description}}</h3>
<p><em> {{carousel[i].name}}, <span>{{carousel[i].affiliation}}</span></em></p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>

carousel slider displays single item in Angular4

Working in an Angular4 project in this ,I have used carousel for displaying products,Products are binding from API response .
In my carousel I display the products like single row 3 column format ,If API returns 10 products the 10 th product is get displayed single slide .
I want to merge the 10th product with 1st and 2nd product then display like a 3 column slide .
Html
<div class="col-sm-9">
<section class="container">
<div class="row">
<div class="col-sm-1">
<i class="fa fa-user" style="font-size:25px"></i>
</div>
<div class="col-sm-9">
<h5>Popular Products</h5>
</div>
</div>
</section>
<hr>
<section class="carousel slide" id="myCarousel">
<div class="container">
<div class="row">
<div class="col-sm-12 text-right mb-4">
<a class="btn btn-outline-secondary carousel-control left" href="#myCarousel" data-slide="prev" title="go back">
<i class="fa fa-lg fa-chevron-left"></i>
</a>
<a class="btn btn-outline-secondary carousel-control right" href="#myCarousel" data-slide="next" title="more">
<i class="fa fa-lg fa-chevron-right"></i>
</a>
</div>
</div>
</div>
<div class="container p-t-0 m-t-2 carousel-inner">
<div class="row row-equal carousel-item {{ i == 0 ? 'active' : '' }} m-t-0" *ngFor="let chunkProducts of productData;let i =index;">
<div class="col-sm-4" *ngFor="let slider of chunkProducts;">
<div class="card">
<div class="card-img-top card-img-top-250 one">
<img class="img-fluid" [src]="slider['PRODUCT_IMAGE']" alt="Carousel 1">
<img routerLink="/my-cart" class="img-fluid two" [src]="slider['PRODUCT_IMAGE_ONHOVER']" alt="Carousel 1">
</div>
<div class="card-block pt-2">
<div class="col-sm-12 text-center card-text">
<span>{{slider.PRODUCT_NAME}}</span>
<br>
<input type="hidden" value="{{slider.PRODUCT_ID}}" #Pname1>
<br>
<span>{{slider.PRODUCT_PRICE}}</span>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
This is my html file to show the slide as 3 column format.
Component
ngOnInit() {
this.CartdataService.get_New_Products().subscribe(
data => {
this.productData = this.chunks(data,3);
console.log(this.productData);
});
chunks(array, size) {
let results = [];
results = [];
while (array.length) {
results.push(array.splice(0, size));
}
return results;
}
Just Change :
this.CartdataService.get_New_Products().subscribe(data => {
this.productData = this.chunks(data.json(),3);
let last = this.productData[this.productData.length-1].length;
if(this.productData.length > 1 && last < 3) {
this.productData[this.productData.length-1] = [ ...this.productData[this.productData.length-1] , ...this.productData[0].slice(0, 3-last) ];
}
});
WORKING DEMO