Angular 8 display one image at a time - html

I am trying to display an avatar for each object that I have. The object is located in a MongoDB database and it is also displayed one by one. The problem that I have is that if I display the images as I display the objects (let's say I have 3 objects displayed), it shows all the 3 avatars for each object displayed, not just one image for each object. This is my code:
<ng-container *ngFor="let e of InstructorData">
<mat-card class="example-card" *ngIf="e.slope === 'Sinaia'">
<mat-card-header>
<div mat-card-avatar class="margin" *ngFor="let avatar of imagesData1">
<img class="example-header-image" mat-card-image [src]="avatar" >
</div>
<mat-card-title>{{e.name}} {{e.surname}}</mat-card-title>
<mat-card-subtitle>{{e.phoneNumber}}</mat-card-subtitle>
<mat-card-subtitle>{{e.email}}</mat-card-subtitle>
</mat-card-header>
<mat-card-content>
<p>{{e.description}}</p>
</mat-card-content>
</mat-card>
</ng-container>
imagesData1: any = [
"./assets/img/ski1.jpg",
"./assets/img/ski2.jpg",
"./assets/img/ski3.jpg"
];

You need to modify your code to below you don't need to iterate over all the images just fetch the image according parent loop key it will always print single image
<ng-container *ngFor="let e of InstructorData; let key = index">
<mat-card class="example-card" *ngIf="e.slope === 'Sinaia'">
<mat-card-header>
<div mat-card-avatar class="margin">
<img class="example-header-image" mat-card-image [src]="imagesData1[key]" >
</div>
<mat-card-title>{{e.name}} {{e.surname}}</mat-card-title>
<mat-card-subtitle>{{e.phoneNumber}}</mat-card-subtitle>
<mat-card-subtitle>{{e.email}}</mat-card-subtitle>
</mat-card-header>
<mat-card-content>
<p>{{e.description}}</p>
</mat-card-content>
</mat-card>
</ng-container>

Related

Can't use mat-grid-list ERROR DOMException: Failed to execute 'setAttribute' on 'Element': ',' is not a valid attribute name

<mat-grid-list cols="3", rowHeight="4:3" >
<mat-grid-tile *ngFor="let itemCard of itemCards">
<!--<ul>-->
<!-- <li *ngFor="let itemCard of itemCards">-->
<mat-card class="card">
<mat-card-header>
<div mat-card-avatar class=""></div>
<mat-card-title>
{{itemCard.brand}}
</mat-card-title>
<img mat-card-avatar src="https://material.angular.io/assets/img/examples/shiba2.jpg" alt="Photo of a Shiba Inu">
<mat-card-subtitle>
{{itemCard.model}}
</mat-card-subtitle>
</mat-card-header>
<img mat-card-image src="" alt="Photo of a Shiba Inu">
<mat-card-content>
<p>
{{itemCards}}
{{itemCard.descriere}}
</p>
<div>Price {{itemCard.price}}</div>
<div>Size {{itemCard.size}}</div>
</mat-card-content>
<mat-card-actions>
<button mat-button>Add to Cart</button>
<!-- <button mat-button>Favorites</button>-->
</mat-card-actions>
</mat-card>
<!-- </li>-->
<!--</ul>-->
</mat-grid-tile>
</mat-grid-list>
Hello, I create a mat-card template and I'm trying to display data from backend into a mat-grid-list with cards as you can see in the code from above and i get this Error : "main.ts:11 ERROR DOMException: Failed to execute 'setAttribute' on 'Element': ',' is not a valid attribute name." I dont'know how to repair this please help me. I mention that i try the exact same thing but i use as you can see commented in the code and it worked but with grid list don't.
there is comma in between the attributes
<mat-grid-list cols="3", rowHeight="4:3" >
// should be
<mat-grid-list cols="3" rowHeight="4:3" >

How to use image url stored in Firestore

I have an image uploaded to Firestore storage which I want to display on my website. I am then storing the url for this image in my Firestore document:
I can successfully reference the data for this document and all the others in the collection, then display in my html as so:
<ng-container *ngIf="infinite | async as products">
<cdk-virtual-scroll-viewport itemSize="100" (scrolledIndexChange)="nextBatch($event, (products[products.length - 1].data.productName))">
<div class="product-row" fxLayout="row wrap" fxLayout.xs="column wrap" fxFlexFill fxLayoutAlign="center center">
<div fxFlex.gt-xs="50%" fxFlex.gt-md="30%" *cdkVirtualFor="let p of products; let i = index; trackByIndex">
<mat-card class="product-tile">
<img class="product-thumbnail" src="p.data.thumbnail" [routerLink]="p.id">
<div class="product-brand">
{{ p.id }}
</div>
<div class="product-details">
<span id="product-name">{{ p.data.productName }}</span> <span id="product-price">{{ p.data.price }}</span>
</div>
<div class="add-to-pad-button">
<button (click)="openDialog(p.id)" mat-raised-button color="accent">Add to Pad</button>
Click Me
</div>
</mat-card>
</div>
</div>
</cdk-virtual-scroll-viewport>
</ng-container>
In theory, I would assume that calling the reference to thumbnail, which is the image URL, would result in the image being displayed. However, the result is:
Am I incorrectly referencing the image URL?
Change p.data.thumbnail to {{ p.data.thumbnail }}

Hovering over mat-card

How to show mat-card-action on hover over card. When i hover over one card it shows action for every card.
<mat-card (mouseover)="hover=true" (mouseleave)="hover=false" [className]="flashcard.privatno ? 'privatno' : 'javno'" *cdkVirtualFor = "let flashcard of flashcards; let i = index" (click)="loadOne(i)">
<mat-card-content>
<p>{{seci(flashcard.pitanje)}}</p>
</mat-card-content>
<mat-card-actions >
<button mat-button *ngIf="hover==true">LIKE</button>
</mat-card-actions>
[Hovering over first card. It should show only LIKE on that card and not on the other][1]
[1]: https://i.stack.imgur.com/36Bsp.png
When you say *ngIf="hover==true" you are comparing all the elements of the for loop with the same variable, that's why all will display/hide at the same time. You need a way to differentiate each element. If your flashcard item have an id, you can try something like this:
.html:
<mat-card (mouseover)="toggleHover(flashcard.id)" (mouseleave)="removeHover()" [className]="flashcard.privatno ? 'privatno' : 'javno'" *cdkVirtualFor = "let flashcard of flashcards; let i = index" (click)="loadOne(i)">
<mat-card-content>
<p>{{seci(flashcard.pitanje)}}</p>
</mat-card-content>
<mat-card-actions >
<button mat-button *ngIf="hoveredElement === flashcard.id ">LIKE</button>
</mat-card-actions>
</mat-card>
.ts
public hoveredElement:any;
toggleHover(id) {
this.hoveredElement = id
}
removeHover() {
this.hoveredElement = null;
}

Using shadow on mat-card in angular

I am working on a project with an angular frontend and I am trying to add a shadow to one of my components and have read that class="mat-elevation-z8" should do the trick. However, it does not do anything.
My html :
<mat-card class="mat-elevation-z8" style="height: 400px; width: 400px;">
<mat-card-header>
<mat-card-title *ngIf="message">{{(message.title | truncateword: 25) | slice:0:30}}</mat-card-title>
<mat-card-subtitle *ngIf="message">{{message.publishedAt | date}}</mat-card-subtitle>
</mat-card-header>
<img *ngIf="image" [src]="image" alt="Here might be a preview image" mat-card-image>
<mat-card-content>
<p *ngIf="message">
{{(message.summary | truncateword:70 | slice:0:73)}}
</p>
</mat-card-content>
</mat-card>
Also, I am importing ~#angular/material/theming in my styles.css, so that should not be the problem either. Here is the styles in my angular.json:
"styles": [
"./node_modules/#angular/material/prebuilt-themes/deeppurple-amber.css",
"src/styles.scss"
],
Any ideas?
You should try on :
#import '~#angular/material/prebuilt-themes/deeppurple-amber.css';
Angular material mat card shadow can be toggled using [class.mat-elevation-z8] attribute
<mat-card [class.mat-elevation-z8]="false">
Example
</mat-card>

mwlDraggable (Drag & Drop) - minimum length of move

I have a problem with mat-card, that is draggable and also contains some button. Unfortunately, on my PC button (click) don't work at all, on my collegue it works sometimes. We think that it can be caused as click is treated as dragging element. Is there anyway to set minimal length of move (dragging), which causes starting treating object as moved?
It was tested on 2 machines - the same code, different behaviour - one one (click) on button is never executed, on second one - sometimes.
What I found now on my computer - while I'm debugging it (Chrome) - when I move my mouse cursor over cards on one of cases occurring this - I get blue "shadow" over the whole app from debugger, but button is clickable - it works as I expected, otherwise - not.
<mat-card mwlDraggable *ngFor="let item of items; let i = index" [dragActiveClass]="'field-dragged'"
[dropData]="item" (dragEnd)="itemFieldDragEnd($event, item)">
<mat-card-content>
<div class="pull-left m-t-5">
{{item.name}}
<div class="field-meta truncate">
{{item.desc}}
</div>
</div>
<div class="pull-right">
<button mat-icon-button (click)="onItemFieldClick($event, item)" matTooltip="somehint">
<mat-icon class="md-24">arrow_forward_ios</mat-icon>
</button>
</div>
</mat-card-content>
</mat-card>
I want to obtain way to force mwlDraggable to become draggable only if it was moved really by let's say 10px, not before. Or any other solution that would work for that problem.
I found solution on github: https://github.com/mattlewis92/angular-draggable-droppable/issues/53
Exemplary fully implemented solution using above:
<mat-card mwlDraggable *ngFor="let item of items; let i = index" [dragActiveClass]="'field-dragged'"
[dropData]="item" (dragEnd)="itemFieldDragEnd($event, item)"
[validateDrag]="dragThresholdValidator">
<mat-card-content>
<div class="pull-left m-t-5">
{{item.name}}
<div class="field-meta truncate">
{{item.desc}}
</div>
</div>
<div class="pull-right">
<button mat-icon-button (click)="onItemFieldClick($event, item)" matTooltip="somehint">
<mat-icon class="md-24">arrow_forward_ios</mat-icon>
</button>
</div>
</mat-card-content>
</mat-card>
public dragThresholdValidator({ x, y }: any): boolean {
const min_drag_threshold = 5;
return Math.abs(x) > min_drag_threshold || Math.abs(y) > min_drag_threshold;
}