Angular 9 won't display image - html

I'm training with angular, i'm trying to display article's avatar that posted during registration, but image not appear correctly.
in the html :
<ng-container *ngIf="blogpost$ | async as bp; else loading">
<div class="card text-white bg-secondary mb-3" style="max-width: 18rem;">
<img class="card-img-top" [src]="imagePath + bp[0].images">
<div class="card-header">{{ bp[0].title }}</div>
<div class="card-body">
<h5 class="card-title">{{ bp[0].subtitle }}</h5>
<p class="card-text">
{{ bp[0].content }}
</p>
</div>
<i class="material-icons" style="cursor: pointer;" [routerLink]="['edit']">
edit
</i>
</div>
</ng-container>
<ng-template #loading>Loading post ...</ng-template>
this [src]="imagePath + bp[0].images doesn't work
my imagePath variable is stored in environment.ts:
imagePath= 'http://localhost:3000/'(back-server)
The image doesn't appear and i've got this error "http://localhost:4200/undefined28-09-08_1609.jpg 404 (Not Found)".
[src]="bp[0].images" this doesn't work either.
article creation component:
import { Component, OnInit, ElementRef } from '#angular/core';
import { FormGroup, FormBuilder } from '#angular/forms';
import { BlogpostService } from '../blogpost-service';
import { Router } from '#angular/router';
#Component({
selector: 'app-blogpost-creation',
templateUrl: './blogpost-creation.component.html',
styleUrls: ['./blogpost-creation.component.css'],
})
export class BlogpostCreationComponent implements OnInit {
creationForm: FormGroup;
fileToUpload: File = null;
uploadPath: string = null;
constructor(private router: Router, private fb: FormBuilder, private blogPostService: BlogpostService) {}
ngOnInit() {
this.createForm();
}
createForm() {
this.creationForm = this.fb.group({
title: '',
subTitle: '',
content: '',
images: '',
});
}
createBlog() {
if (this.creationForm.valid) {
if (this.fileToUpload) {
this.blogPostService.uploadImage(this.fileToUpload).subscribe(
data => console.log('image', data),
error => console.log('error', error),
);
}
console.log('formGrp', this.creationForm);
this.blogPostService.createBlogPost(this.creationForm.value).subscribe(
data => console.log('DATA posted', data),
error => this.handleError(error),
);
if (this.creationForm.value) {
this.router.navigate(['']);
}
} else if (this.creationForm.valid) {
this.blogPostService.createBlogPost(this.creationForm.value).subscribe(
data => (this.fileToUpload = null),
error => this.handleError(error),
);
}
}
handleFileInput(event) {
this.fileToUpload = event.target.files[0];
console.log('uploaded file', this.fileToUpload);
}
handleSuccess(data) {
console.log('Post send', data);
}
handleError(error) {
console.log('Error when try to send post', error);
}
}
If someone have an idea to load an image! thank you :)

The error is pretty explanatory.
"http://localhost:4200/undefined28-09-08_1609.jpg 404 (Not Found)"
You defined imagePath in environment.ts but you also need to import that in your component.
When you write <img class="card-img-top" [src]="imagePath + bp[0].images">, Angular will look for imagePath defined in your component.
Following should solve your problem
import { environment } from 'environments/environment';
export class BlogpostCreationComponent implements OnInit {
imagePath = environment.imagePath;
}

Related

My codes are not doing get,set,post so what is my codes error how can i fix it?

these are my .ts codes i write these becasue i want to get product details and delete
import { Component, OnInit } from '#angular/core';
import {FormGroup,FormBuilder, FormControl, Validators} from "#angular/forms"
import { ToastrService } from 'ngx-toastr';
import { Product } from 'src/app/models/product';
import { ProductService } from 'src/app/services/product.service';
import { LocalStorageService } from 'src/app/services/local-storage.service';
import { Router } from '#angular/router';
#Component({
selector: 'app-product-delete',
templateUrl: './product-delete.component.html',
styleUrls: ['./product-delete.component.css']
})
export class ProductDeleteComponent implements OnInit {
products: Product[] = [];
dataLoaded = false;
deleteProductForm:FormGroup;
product :Product
productId :number;
constructor(private formBuilder:FormBuilder,
private productService:ProductService
, private toastrService:ToastrService
,private router:Router,
private localStorageService:LocalStorageService) { }
ngOnInit(): void {
this.createdeleteProductForm();
}
createdeleteProductForm(){
this.deleteProductForm = this.formBuilder.group({
productId:["", Validators.required],
})
}
getbyid() {
Number(localStorage)
Number(this.productService)
this.productService.getbyid(Number(localStorage.getItem("productId"))).subscribe(
(response) => {
this.products = response.data;
this.dataLoaded = true;
this.deleteProductForm.setValue({
productId: this.product,
categoryId: this.product.categoryId,
productName: this.product.productName,
unitPrice: this.product.unitPrice
});
},
(responseError) => {
this.toastrService.error(responseError.error);
}
)
}
deleteProduct() {
if (this.deleteProductForm.valid) {
let productModel = Object.assign({}, this.deleteProductForm.value);
productModel.productId=parseInt(productModel.productId);
this.productService.delete(productModel).subscribe(
(response) => {
this.toastrService.success('Lütfen tekrar giriş yapınız');
this.router.navigate(['/login']);
},
(responseError) => {
this.toastrService.error(responseError.error);
}
);
} else {
this.toastrService.error('Bir hata oluştu.');
}
}
}
these are my html codes i trying to do when user sign in a productId after that click the button delete the product in that ıd
<div class="card">
<div class="card-header"><h5 class="title">Ürün Sil</h5></div>
<div class="card-body">
<form [formGroup]="deleteProductForm">
<div class="mb-3">
<label for="productId">ÜrünId'si</label>
<div class="form-group">
<input type="number"
id="productId"
formControlName="productId" class="form-control"
placeholder="productId"/>
</div>
<div class="card-footer" style="background-color: rgb(4, 62, 255)">
<button
class="btn btn-lg btn-outline-success float-end"
(click)="deleteProduct()"
>
Sils
</button>
</div>
and these are my service
delete(product:Product):Observable<ResponseModel>{
let newPath = this.apiUrl + 'products/delete';
return this.httpClient.post<ResponseModel>(newPath, product );
}
getbyid(productId:number) : Observable<ListResponseModel<Product>> {
let newPath = this.apiUrl + 'products/getbyid?productId=' + productId;
return this.httpClient.get<ListResponseModel<Product>>(newPath);
}
what i'm going for is that when the user goes on a productId click the button, I want to delete the data including the Id first, but what's the null time on main at the moment?
note:Value cannot be null. says back-end
in html POST https://localhost:44314/api/products/delete
[HTTP/2 500 Internal Server Error 9591ms gives this error
First of all, have you checked the value of product in the call of delete ?
Also, maybe it's the httpClient.delete you need since it's the best way to delete an object to the back end. I suggest this:
https://angular.io/guide/http#making-a-delete-request

Best way to implement a pageable to Angular Project

I have products in my database and I have created controller on my backend app that I tested and works really good, so now I need to implement that to my frontend. I have product.component.ts file that looks like this
import { Component, OnInit } from "#angular/core";
import { FormControl, FormGroup } from "#angular/forms";
import { debounceTime, switchMap } from "rxjs";
import { ProductService } from "./product.service";
#Component({
selector: 'app-product',
templateUrl: './product.component.html'
})
export class ProductComponent implements OnInit {
products: any[] = [];
productSearchForm!: FormGroup;
page: number = 0;
size: number = 4;
constructor(
private productService: ProductService
) { }
loadMore() {
this.page = this.page+1;
this.productSearchForm.get('searchTerm')?.valueChanges
.pipe(
debounceTime(500),
switchMap(value => {
return this.productService.searchByTermPageable(value, this.page, this.size);
})
).subscribe(data => {
this.products = data;
}, error => {
console.log(error);
// this.products = [];
});
}
ngOnInit(): void {
this.initializeForm();
this.productSearchForm.get('searchTerm')?.valueChanges
.pipe(
debounceTime(500),
switchMap(value => {
return this.productService.searchByTermPageable(value, this.page, this.size);
})
).subscribe(data => {
this.products = data;
}, error => {
console.log(error);
// this.products = [];
});
}
private initializeForm(): void {
this.productSearchForm = new FormGroup({
searchTerm: new FormControl(null)
});
}
}
searchTerm is a query param that is used to find products with name starting with that term. I call function from file product.service.ts that looks like this
import { HttpClient } from "#angular/common/http";
import { Injectable } from "#angular/core";
import { Observable } from "rxjs";
import { environment } from "src/environments/environment";
#Injectable({ providedIn: 'root'})
export class ProductService {
constructor(private httpClient: HttpClient) { }
searchByTerm(searchTerm: string): Observable<any> {
const url = `${environment.apiUrl}product/search/by-name-or-desc?term=${searchTerm}`;
return this.httpClient.get(url);
}
searchByTermPageable(searchTerm: string, page: number, size: number): Observable<any> {
const url = `${environment.apiUrl}product/search/by-name-or-desc?term=${searchTerm}&page=${page}&size=${size}`;
return this.httpClient.get(url);
}
}
When I click the button load more I want to load next 4 products from database, but keep the first 4 products on my html page, so what is the best way to do this? This is my html page, and also I am using Bulma as my css framework
<div class="mt-5">
<form>
<div class="field" [formGroup]="productSearchForm">
<div class="control has-icons-left">
<input class="input" type="text" formControlName="searchTerm" placeholder="Find products">
<span class="icon is-small is-left">
<i class="fas fa-search"></i>
</span>
</div>
</div>
<hr />
</form>
</div>
<div class="columns">
<div class="column" *ngFor="let product of products">
<div class="card">
<div class="card-content">
<div class="media">
<div class="media-content">
<p class="title is-4">{{ product.name }}</p>
<p class="subtitle is-6">{{ product.category?.name}}</p>
</div>
</div>
<div class="content">
{{ product.description }}
</div>
</div>
</div>
</div>
</div>
<button type="button" class="button is-primary" (click)="loadMore()">Load more...</button>
You can to have a new function in your service that return the elements of the page plus the other elements search. If you has a function that return the paginate elements
searchByTermPageable(search:string,page:number,size:number)
{
...
}
Some like
product:any[]=[] //define an empty array where you store the product
searchOld:string=null //and a variable to store the search
getData(search:string,page:number,size:number)
{
if (search!=this.searchOld) //if is a new search
{
this.searchOld=search
this.product=[]
}
return this.searchByTermPageable(search,page,size).pipe(
map((res:any[])=>[...this.product,...res]), //concat the before store product
tap((res:any[])=>{
this.product=res //store in the product the new array
})
)
}
Allow you some like
<div *ngFor="let product of product$|async">
{{product.name}}
</div>
<button (click)="more()">more</button>
pageIndex:number=-1;
product$:Observable<any[]>
more()
{
this.pageIndex++
this.product$=this.dataService.getData("",this.pageIndex,4)
}
The other solution is search all the product and simple use slice pipe
<div *ngFor="let product of allProduct$|async |slice:0:(index+1)*pageSize">
{{product.name}}
</div>
<button (click)="index=index+1">more</button>
a litle stackblitz

Angular 13 Parent-Child not Communicating

Trying to get an array from a parent component to a child component. The Angular docs make it look really simple but I'm not sure what I'm doing wrong. The variable is activePost. Angular version is 13
Parent ts file (HomepageComponent):
import { Component, OnInit } from '#angular/core';
import { PostService } from 'src/app/services/post.service';
import { map } from 'rxjs/operators';
import { Post } from 'src/app/models/post.model';
import { ActivatedRouteSnapshot, Router } from '#angular/router';
import { PostDisplayComponent } from '../components/post-display/post-display.component';
#Component({
selector: 'app-homepage',
templateUrl: './homepage.component.html',
styleUrls: ['./homepage.component.scss']
})
export class HomepageComponent implements OnInit {
posts?: Post[];
category?:'';
currentpost?: Post;
currentIndex = -1;
title = '';
content='';
activePost: Post;
images: string[] =["../assets/img/damwon.jpg",
"../assets/img/FPX.jpg",
"../assets/img/2015skt.webp",
"../assets/img/2017SSG.webp",
"../assets/img/2014SSW.webp",
"../assets/img/TPA.webp",
"../assets/img/Fnatic.webp"]
backgroundImage: string = '';
constructor(private PostService: PostService,
private route: Router) { }
ngOnInit() {
let ran = Math.floor(Math.random()*6);
console.log(ran, Math.random()*100)
this.backgroundImage = this.images[ran];
this.retrieveposts();
}
refreshList(): void {
this.currentpost = undefined;
this.currentIndex = -1;
this.retrieveposts();
}
retrieveposts(): void {
this.PostService.getAll().snapshotChanges().pipe(
map(changes =>
changes.map(c =>
({ id: c.payload.doc.id, ...c.payload.doc.data() })
)
)
).subscribe(data => {
this.posts = data;
});
}
setActivepost(post: Post, index: number): void {
this.currentpost = post;
this.currentIndex = index;
console.log("Post:", post, "Index:", index);
this.activePost = this.currentpost
this.route.navigate(['/Read/'])
}
}
Child ts file (post-display component)
import { Component, OnInit, Input, OnChanges, Output, EventEmitter } from '#angular/core';
import { Post } from 'src/app/models/post.model';
import { PostService } from 'src/app/services/post.service';
import { HomepageComponent } from 'src/app/homepage/homepage.component';
#Component({
selector: 'app-post-display',
templateUrl: './post-display.component.html',
styleUrls: ['./post-display.component.scss']
})
export class PostDisplayComponent implements OnInit {
#Input() activePost: Post;
#Output() refreshList: EventEmitter<any> = new EventEmitter();
currentPost: Post = {
title: '',
description: '',
category:'',
published: false,
content: ''
};
message = '';
constructor(private PostService: PostService) { }
ngOnInit(): void {
console.log(this.activePost)
}
}
Child HTML:
<div class="container" style="padding-top: 200px;">
<div class="post">
ACTIVE POST HERE:
{{activePost}}
</div>
Looking at the console, the child component always returns undefined for activePost. I'm not sure if this is because I dont have anything in the parent html code for the child to look at? I feel like I should just be able to do this in the .ts file.
Help would be appreciated. Let me know if there are other project docs I should share as well.
Edit, added parent html:
<header class="header" [ngStyle]="{'background-image': 'url(' + backgroundImage + ')'}">
<div class="content">
<h1 class="heading">
<span class="small">Samsite:</span>
Stat
<span class="no-fill">check</span>
</h1>
<!--write a blog-->
</div>
</header>
<section class="blogs-section">
<div class="blog-card"
*ngFor="let post of posts; let i = index"
>
<h1>Title: {{ post.title }}</h1>
<h2> Category: {{ post.category }}</h2>
<p class="blog-overview"> Preview: {{ post.description }}</p>
<div class="btn" (click)="setActivepost(post, i)">Read!</div>
</div>
</section>

Problem with My Wish List Items Showing Source unknown

I am having a problem showing my wish list items on the page. I'm using Angular 10 and json. Wen I click to add to favorites it color the heart and add it to to my json folder under wishlistitem, but when I route to page to look at the items no products are there. I can tell it hits the the *ngFor because the pipe for the dollar amount for each item appears but no images. When inspecting the source it shows src=unknown.
I have two folders wishlist-list and wishlistitem. I have a service for wishlistitem that is where I think my problem resides. I have included my code.
import { Component, OnInit, Input } from '#angular/core';
import {ProductService} from 'src/app/services/product.service'
import { MessengerService } from 'src/app/services/messenger.service';
import { WishlistService } from 'src/app/services/wishlist.service';
import { WishlistItemService } from '#app/services/wishlist-item.service';
import { Wish} from 'src/app/models/wish';
import {Product} from 'src/app/models/product';
#Component({
selector: 'app-wishlist-list',
templateUrl: './wishlist-list.component.html',
styleUrls: ['./wishlist-list.component.scss']
})
export class WishlistListComponent implements OnInit {
productList: Product[]= [];
wishlistItem: Wish[]= [];
wishItem = []
constructor( private msg: MessengerService,
private productService: ProductService,
private wishlistService: WishlistService,
private _wishlistitemService: WishlistItemService ) { }
ngOnInit(): void {
this.loadWishlistList();
}
loadWishlistList(){
this._wishlistitemService.getWishlistitem().subscribe((items: Wish[]) => {
this.wishItem= items;
this.msg.sendMsg("Is the item being captured" + items)
})
}
}
//Here is my Wishlist-list HTML
<p>wishlist-list works!</p>
<div class="container">
<div class="row">
<div class="col-md-2" *ngFor="let product of wishItem">
<app-wishlistitem [wishitemItem]="product"></app-wishlistitem>
</div>
</div>
</div>
//Here is my wishlist item service
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http';
import { wishlistitemUrl } from 'src/app/config/api';
import { map } from 'rxjs/operators';
import { ProductItemComponent } from '#app/shopping-cart/product-list/product-
item/product-item.component';
import { Observable, of } from 'rxjs';
import { catchError} from 'rxjs/operators';
import {Product} from 'src/app/models/product';
import {Wish} from 'src/app/models/wish';
#Injectable({
providedIn: 'root'
})
export class WishlistItemService {
product:any
wishlistitemUrl = 'http://localhost:3000/wishlistitem';
constructor(private http: HttpClient) { }
getWishlistitem(): Observable<Wish[]>{
return this.http.get<Wish[]>(wishlistitemUrl)
.pipe(
map((result: any[]) => {
let wishItem: Wish[]= [];
for(let item of result) {
let productExists = false
if (!productExists){
wishItem.push(new Wish(item.id, item.name, item.description,
item.price, item.imageUrl);
}
}
return wishItem;
})
);
}
addProductToWishlistItem(product:Wish):Observable<any>{
return this.http.post(wishlistitemUrl, {product});
}
}
//Here is wishlistitem
import { Component, Input, OnInit } from '#angular/core';
import { ProductService } from 'src/app/services/product.service'
import { WishlistService } from 'src/app/services/wishlist.service';
import { WishlistItemService } from '#app/services/wishlist-item.service';
import { MessengerService } from 'src/app/services/messenger.service';
import { map } from 'rxjs/operators';
import { Wish } from '#app/models/wish';
import { Product } from '#app/models/product';
#Component({
selector: 'app-wishlistitem',
templateUrl: './wishlistitem.component.html',
styleUrls: ['./wishlistitem.component.scss']
})
export class WishlistitemComponent implements OnInit {
#Input() wishitemItem: Wish
#Input() productItem: Product
#Input() product: string
constructor(private wishlistService: WishlistService, private _wishlistitemService:
WishlistItemService, private msg:MessengerService ) { }
ngOnInit(): void {
}
//This function works as expected
handleAddToWishlistitem(){
this._wishlistitemService.addProductToWishlistItem (this.wishitemItem).subscribe(()
=>{
alert("Get wish list item");
this.msg.sendMsg(this.wishitemItem)
})
}
}
//Here is wishlistitem Html
<p>wishlistitem works!</p>
<div class="test">
<div class="container" style="margin:0 auto">
<div class="row no-gutters" style="margin-top: 30px">
<div class="col-4">
<img class="shacker" [src]="wishitemItem.imageUrl" />
<div class="card-body">
<p class="card-text" style="text-align:left; width:130px">
{{wishitemItem.name}}</p>
<p class="card-text" style="text-align:left; width:130px;">
<strong>{{ wishitemItem.price | currency }}</strong>
</p>
<p class="card-text" style="text-align:left; width: 150px">
{{wishitemItem.description | slice: 0:20}}...</p>
</div>
</div>
</div>
</div>
</div>
//I hope the explanation is sufficient. I have tried many scenarios, the issue I'm
having is with the property for the wishlist item, carItem does not have a property
and when I create one the application doesn't behave as expected.
Thank you in advance
PDH

dispay json data in ngfor loop in angular (data from firebase)

In my Angular code, I am getting data from a firebase database through an Http get request and when I try to display the result with an ngfor loop, I have an error message. This example was replicated from a tutorial and it worked for him. Where is the problem and how could I make it work? Thanks for helping!
I use a service to get data here is the code:
import {Http} from '#angular/http';
import { Injectable } from '#angular/core';
import {Response} from "#angular/http";
import {map} from 'rxjs/operators';
#Injectable()
export class ServerService {
constructor(private http:Http){}
StoreServers(servers:any[]){
return this.http.post('https://ng-http-a5718.firebaseio.com/data.json',servers);
}
GetServers(){
return this.http.get('https://ng-http-a5718.firebaseio.com/data.json').pipe(map(
(res:Response) =>{
const dataserver = res.json() as any[];
for(const server of dataserver ){
server.name='fetched_server'+server.name
}
return dataserver;
}
)
)
}
}
Here is the .ts code of the component where I try to display the data:
import { Component } from '#angular/core';
import { ServerService } from './server.service';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
constructor(private ServerService : ServerService){}
servers = [
{
name: 'Testserver',
capacity: 10,
id: this.generateId()
},
{
name: 'Liveserver',
capacity: 100,
id: this.generateId()
}
];
onAddServer(name: string) {
this.servers.push({
name: name,
capacity: 50,
id: this.generateId()
});
}
private generateId() {
return Math.round(Math.random() * 10000);
}
OnSave(){
this.ServerService.StoreServers(this.servers).subscribe(
(Response)=>(console.log(Response)),
(Error)=>(console.log(Error))
)
}
OnGet(){
this.ServerService.GetServers().subscribe(
(data) => { this.servers=data}
,
(Error)=>{
return (console.log(Error));
}
)
}
}
Here is the html code of the component where I try to display the data:
<div class="container">
<div class="row">
<div class="col-xs-12 col-sm-10 col-md-8 col-sm-offset-1 col-md-offset-2">
<input type="text" #serverName>
<button class="btn btn-primary" (click)="onAddServer(serverName.value)">Add Server</button>
<hr>
<button class="btn btn-primary" (click)='OnSave()'>Save servers</button>
<button class="btn btn-primary" (click)='OnGet()'>Get servers</button>
<br>
<ul class="list-group" *ngFor="let server of servers">
<li class="list-group-item">{{ server.name }} (ID: {{ server.id }})</li>
</ul>
</div>
</div>
</div>
And finally here it is the error message I get:
enter image description here
this.server expecting Array in onGet() method but getting Object from firebase with the unique key. so you can modify onGet() method in following:
OnGet(){
this.ServerService.GetServers().subscribe(
(data) => {
const keys = Object.keys(data);
const firstKey = keys[0];
this.servers = data[firstKey]; // get the inside array
}
,
(Error)=>{
return (console.log(Error));
}
)
}