How to bypassSecurityTrustResourceUrl for each element in an array? - javascript

I have an array of Google Map Embed API URLs. However, when iterating over each item and binding them to the source of an iFrame.
I could use the following.
constructor(private sanitizer: DomSanitizationService) {
this.url = sanitizer.bypassSecurityTrustResourceUrl('https://www.google.com/maps/embed/v1/place?key=KEY&q=365 Badger Ave, Newark, New Jersey 07112');
}
But, I would have to do this for each item and I can't do so since I receive the array from an external source that updates.
How could I bypass the security for each of my URLs?
Here's app.component.ts
import { Component, Pipe } from '#angular/core';
import { DomSanitizationService } from '#angular/platform-browser';
#Pipe({name: 'secureUrl'})
export class Url {
constructor(private sanitizer:DomSanitizationService){
this.sanitizer = sanitizer;
}
transform(url) {
return this.sanitizer.bypassSecurityTrustResourceUrl(url).changingThisBreaksApplicationSecurity;
}
}
#Component({
selector: 'my-app',
pipes: [Url],
template: `
<div class="container">
<div style="padding-top: 20px">
<div class="row" *ngFor="let row of rows">
<div *ngFor="let event of row">
<div class="col s12 m6 l4">
<div class="card hoverable">
<div class="card-image waves-effect waves-block waves-light">
<img height="300" class="activator" [src]="event.thumbnail">
</div>
<div class="card-content">
<span class="card-title activator grey-text text-darken-4">{{event.title}}</span>
<p><a class="activator">Hosted by {{event.host.data.first_name}} {{event.host.data.last_name}}</a></p>
</div>
<div class="card-action grey lighten-2">
<a class="blue-grey-text lighten-3">Details</a>
<a class="blue-grey-text lighten-3">Join</a>
</div>
<div class="card-reveal" style="font-size: 15px">
<span class="card-title grey-text text-darken-4"><center>{{event.title}}</center><i class="material-icons right">close</i></span>
<hr>
<center>
<p class="truncate">{{event.description}}</p>
<hr>
<p>Starts {{event.start}}</p>
<iframe width="210" height="190" frameborder="0" style="border:0" src="{{event.address|secureUrl}}" allowfullscreen></iframe>
</center>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
`
})
export class AppComponent {
public rows = GROUPS;
}
var EVENTS = [
{
id: 95,
title: "Event Name",
description: "The awesome event description",
thumbnail: "https://ucarecdn.com/58955d6b-bd4c-41f3-8a7b-4ce2bf013b13/IMG_4229.JPG",
access: "public",
code: null,
start: "1 week ago",
end: "6 days ago",
address: "https://www.google.com/maps/embed/v1/place?key=KEY",
host: {
data: {
id: 23,
avatar: "http://www.gravatar.com/avatar/9e557072ab393aa2fca6701eb7b23853?s=45&d=mm"
}
},
category: {
data: {
id: 1,
title: "Wedding",
description: "A marriage ceremony."
}
}
}
];
var chunk_size = 3;
const GROUPS = EVENTS.map(function(e,i){
return i%chunk_size===0 ? EVENTS.slice(i,i+chunk_size) : null;
})
.filter(x=>!!x)

You can use PIPE with DomSanitizationService as shown below;
//our root app component
import {Component, Pipe} from '#angular/core'
import {DomSanitizationService} from '#angular/platform-browser';
#Pipe({name: 'secureUrl'})
export class Url {
constructor(private sanitizer:DomSanitizationService){
this.sanitizer = sanitizer;
}
transform(url) {
return this.sanitizer.bypassSecurityTrustResourceUrl(url).changingThisBreaksApplicationSecurity;
}
}
#Component({
selector: 'my-app',
pipes: [Url],
template: `
<div *ngFor="let item of myUrls; let i = index">
{{item.url|secureUrl}}
</div>
`,
})
export class AppComponent {
myUrls=[{url:"google.com"},{url:"google1.com"},{url:"google2.com"}];
}

Related

How to achieve responsive api in Angular?

I need to achieve the responsive page as shown below in the image.
I have created something like this. But my mat-card gets cut or hidden in the tile , when I reduce the browser size. I managed to create this:
Where am I going wrong? Below is my code.
header.component.html
<div fxLayout="column" fxLayout.xs="column">
<mat-toolbar color="primary" >
<button mat-button (click)="side_nav.open()">
<mat-icon>menu</mat-icon>
</button>
<img src="../assets/weather_images/logo.png" style="width: 35px;">
<span> Minimus </span>
<span class="header_text"></span>
<span>TODAY</span>
<span class="header_text"></span>
<span>light</span>
<mat-slide-toggle [checked]="isDarkTheme | async" (change)="toggleDarkTheme($event.checked)"></mat-slide-toggle>
<span>dark</span>
</mat-toolbar>
<mat-sidenav-container [ngClass]="{'dark-theme': isDarkTheme | async}" >
<mat-sidenav #side_nav style="height: 100%;width: 200px;">
<br><br><div class="m"><span routerLink='' (click)="side_nav.close();" > Home </span></div><br><br><br>
<div class="m"><span routerLink='/search-cities' (click)="side_nav.close();">Add City</span></div>
</mat-sidenav>
<mat-sidenav-content><br>
<div [#fade] = "prepareRoute(o)" [#flyInOut] = "prepareRoute(o)">
<router-outlet #o="outlet"></router-outlet>
</div>
</mat-sidenav-content>
</mat-sidenav-container>
</div>
addciyt .component .html
<div>
<mat-grid-list [cols]="breakpoint" (window:resize)="onResize($event)" gutterSize="30px" [ngClass]="{'dark-theme': isDarkTheme | async}">
<mat-grid-tile>
<mat-card class="card_style" [ngClass]="{'dark-theme': isDarkTheme | async}" routerLink="/search-cities" #slideInOut>
<mat-card-title class="card_title" [ngClass]="{'dark-theme': isDarkTheme | async}">ADD CITY</mat-card-title><br>
<img src="../assets/weather_images/plus.png" alt="Plus image" width="150px" class="image_style">
<img mat-card-image src="../assets/weather_images/1.png" height="260px">
</mat-card>
</mat-grid-tile>
<mat-grid-tile *ngFor = "let v of value">
<mat-card class="card_style" [routerLink]="['/details',v.city_name]" #fade>
<mat-card-title class="card_title">
{{value ? (v.city_name).toUpperCase() : ''}}
</mat-card-title><br>
<div *ngIf = "v.des === 'Clouds'" style="text-align: center;">
<img src= "../assets/weather_images/cloudy.png" alt="cloudy" class="image">
</div>
<div *ngIf = "v.des === 'Rain'" style="text-align: center;">
<img src= "../assets/weather_images/raining.png" alt="raining" class="image">
</div>
<div *ngIf = "v.des === 'Clear'" style="text-align: center;">
<img src= "../assets/weather_images/sunny.png" alt="clear" class="image">
</div>
<div *ngIf = "v.des === 'Strom'" style="text-align: center;">
<img src= "../assets/weather_images/strom.png" alt="strom" class="image">
</div>
<div *ngIf = "v.des === 'Snow'" style="text-align: center;">
<img src= "../assets/weather_images/snowing.png" alt="strom" class="image">
</div>
<mat-card-content>
<div>
<p class="temp">{{value ? (v.temp - 273.15).toFixed(2) : ''}}℃</p>
</div>
<p class="main">{{value ? (v.des).toUpperCase() : ''}}</p>
<p style="margin-left: 35px; font-size: 16px;">Temp_min Temp_max</p>
<p class="temp_min">{{value ? (v.temp_min - 273.15).toFixed(2) : ''}}℃<span class="temp_max">{{value ? (v.temp_max - 273.15).toFixed(2) : ''}}℃</span></p>
</mat-card-content>
</mat-card>
</mat-grid-tile>
</mat-grid-list>
</div>
addcity.component.ts
import { Component, OnInit } from "#angular/core";
import { Observable } from "rxjs";
import { ThemeService } from "../services/theme.service";
import { WeatherService } from "../services/weather.service";
import { AngularFireDatabase } from "angularfire2/database";
import { slideInOut, fade } from "../animation";
import { FormControl } from '#angular/forms';
import { map, startWith } from 'rxjs/operators';
#Component({
selector: "app-addcity",
templateUrl: "./addcity.component.html",
styleUrls: ["./addcity.component.scss"],
animations: [
slideInOut,
fade
]
})
export class AddcityComponent implements OnInit {
value: Array<any> = [];
cities: Array<any>;
isDarkTheme: Observable<boolean>;
myControl = new FormControl();
options: string[] = ['One', 'Two', 'Three'];
filteredOptions: Observable<string[]>;
control = new FormControl();
streets: string[] = ['Champs-Élysées', 'Lombard Street', 'Abbey Road', 'Fifth Avenue', 's','d','f','y','u','h','l'];
filteredStreets: Observable<string[]>;
name = '';
breakpoint:number;
constructor(
private themeService: ThemeService,
private db: AngularFireDatabase,
private weatherService: WeatherService
) {
db.list("/user/cities")
.valueChanges()
.subscribe((cities) => {
this.cities = cities;
for (let c of cities) {
this.weatherService.getcities(c['name']).subscribe(value => {
const temp = value["main"].temp;
const temp_min = value["main"].temp_min;
const temp_max = value["main"].temp_max;
const des = value["weather"][0].main;
const city_name = c['name'];
const a = {
temp,
temp_min,
temp_max,
des,
city_name
};
this.value.push(a);
});
}
});
console.log(this.name);
}
ngOnInit() {
this.isDarkTheme = this.themeService.isDarkTheme;
this.breakpoint = (window.innerWidth <= 400) ? 1 : 2;
}
onResize(event) {
this.breakpoint = (event.target.innerWidth <= 400) ? 1 : 2;
}
}
I tried a lot but nothing seems to work.
#DHEERAJ to make your page responsive, you can use different CSS techniques, you can also use the #angular/flex-layout in combination with Angular Material
Find here the Details of #angular/flex-Layout and FlexLayout Examples

How can I configure my <li> items with Angular Routing so that it shows the relevant details in a new view?

I am building an Angular Movie DB, the two components I am working with are the "search-movie" component and the "single-view" component. The "search-movie" component displays a list of movies, the "single-view" component shows further details of a given movie.
I would like it so that when I click on a movie from the list in the "search-movie" component, the page renders the "single-view" component for that movie.
I have managed to set this up so that navigating to the "single-view" path with a movie id (i.e. /movie/tt4425200) directly from the URL, correctly loads up the info for that movie by it's ID, so that's all correctly set up.
I just can't seem to connect the clicking of a movie in the "search-movie" component, to then successfully navigate to the correct "single-view" path. So using the example above, clicking on the relevant movie loads up the "single-view" component with the URL path /movie/tt4425200.
I'm sure that this is a case of using #Input to communicate between the two components, but I just can't figure it out.
search-movie.component.ts:
import { Component, OnInit, Input } from '#angular/core';
import { FormControl } from '#angular/forms';
import { DataService } from '../data.service';
#Component({
selector: 'app-search-movie',
templateUrl: './search-movie.component.html',
styleUrls: ['./search-movie.component.css']
})
export class SearchMovieComponent implements OnInit {
searchControl = new FormControl('');
movieResults: any = [];
constructor(private data: DataService) { }
ngOnInit() {}
/* GET request */
getData(event) {
const film = event.target.value;
this.data.searchFilm(film)
.subscribe( (res) => {
res = this.movieResults = res;
console.log(res);
});
}
}
search-movie.component.html:
<div class="container">
<h1 class="is-size-3">Find your favorite movies...</h1>
<form (ngSubmit)="onSubmit()">
<input
type="text"
(keyup)="getData($event)"
placeholder="Start typing..."
[formControl]="searchControl" />
</form>
{{searchControl.value}}
</div>
<div class="container">
<ul>
<li id="list-item" *ngFor="let x of movieResults; let i = index;">
<img [src]="x.Poster" onerror="this.src='../assets/images/default-poster.jpg'">
<p id="movie-title" class="is-size-5">{{x.Title}} ({{x.Year}}) </p>
</li>
</ul>
</div>
single-view.component.ts:
import { Component, OnInit, Input } from '#angular/core';
import { ActivatedRoute } from '#angular/router';
import { DataService } from '../data.service';
#Component({
selector: 'app-single-view',
templateUrl: './single-view.component.html',
styleUrls: ['./single-view.component.css']
})
export class SingleViewComponent implements OnInit {
singleDetails: any = {};
constructor(
private data: DataService,
private route: ActivatedRoute) { }
ngOnInit() {
/** GENERATE FILM DETAILS BY movie/id where id is the imdbID */
const id = this.route.snapshot.paramMap.get('id');
this.data.moviebyID(id)
.subscribe( (res) => {
res = this.singleDetails = res;
});
}
}
single-view.component.html:
<div class="container singleDisplayContainer">
<div class="columns is-mobile">
<div class="column" id="poster-column">
<img id="poster" [src]="singleDetails.Poster" [alt]="singleDetails.Title" onerror="this.src='../assets/images/default-poster.jpg'">
</div>
<div id="info-column" class="column">
<div class="columns">
<div class="column is-three-fifths">
<h1 class="is-size-3">{{singleDetails.Title}} <span class="is-size-4">({{singleDetails.Year}})</span> </h1>
<p style="font-size: 14px"> {{singleDetails.Rated}} | {{singleDetails.Runtime}} | {{singleDetails.Genre}} | {{singleDetails.Released}} </p>
</div>
<div class="column">
<div class="columns">
<div class="column is-one-third">
<img id="star-rating" width="50px" src="../../assets/images/star-rating.png" alt="{{singleDetails.Title}}">
</div>
<div class="column">
<p style="font-size: 2em"> {{singleDetails.imdbRating}}<span style="font-size: 12px">/10</span></p>
<p>{{singleDetails.imdbVotes}}</p>
</div>
</div>
</div>
</div>
<br>
<p>Plot: {{singleDetails.Plot}} </p>
<br>
<p>Directed by: {{singleDetails.Director}} </p>
<br>
<p>Writers: {{singleDetails.Writer}} </p>
<br>
<p>Actors: {{singleDetails.Actors}} </p>
<br>
<p onerror="this.style.display='none'">Box office: {{singleDetails.BoxOffice}} </p>
</div>
</div>
</div>
In Your UL -> LI, add routerLink property and pass the movie id as the second param
[routerLink]="['/movie/,x.movieId]">
<ul>
<li id="list-item" *ngFor="let x of movieResults; let i = index;" [routerLink]="['/movie/,x.movieId]">
<img [src]="x.Poster" onerror="this.src='../assets/images/default-poster.jpg'">
<p
id="movie-title"
class="is-size-5">{{x.Title}} ({{x.Year}}) </p>
</li>
</ul>
Looks like you have everything set up, all you need to do is navigate to single-view on click of the movie.
search-movie.component.ts
showDetails(id : string) {
this.router.navigate(['movie',{ id }]);
}
search-movie.component.html
<!-- in showDetails you will pass id of the current movie while looping -->
<li id="list-item" *ngFor="let x of movieResults; let i = index;" (click)="showDetails(x.id)">
<img
[src]="x.Poster"
onerror="this.src='../assets/images/default-poster.jpg'"
>
<p
id="movie-title"
class="is-size-5">{{x.Title}} ({{x.Year}}) </p>
</li>
This will navigate to single-view page. is this what you want right?
or you need to load single-view in the same page as the list?

Angular: #Input value available in template, but not in component

So I'm sending a movie object from a parent to a child component. I use #Input from the core module to do this.
Now, I am able to use this data inside the template to display my view, but when I try to access it in for example editReview() then this.movie returns undefined.
Does anyone know how to fix this?
Child Component: the console.log returns undefined
export class ReviewListComponent implements OnInit {
#Input('movie') movie;
constructor(private reviewService: ReviewService){}
editReview() {
console.log(this.movie);
}
}
Child Component Template: I am able to display my name and the content of the review. What's not working unfortunately is when I click the button it says that this.movie is undefined
<ul class="list-group">
<li *ngFor="let review of movie?.reviews" class="list-group-item">
<p>{{review.user.firstName}} {{ review.user.lastName}}</p>
<hr>
<p>{{review.content}}</p>
</li>
</ul>
<button (click)="editReview()">Button</button>
Edit: I added the components and templates of the two parent components: The first one is the movie component where I retrieve the movie object asynchronously, the second is the review component which contains the review-list component that I had already posted above
movie.component.ts
import {Component, OnInit} from "#angular/core";
import { MovieService} from "./movie.service";
import {ActivatedRoute} from "#angular/router";
#Component({
selector: 'app-movie',
templateUrl: './movie.component.html',
styleUrls: ['./movie.component.css']
})
export class MovieComponent implements OnInit{
rating;
movie;
movieId;
constructor(private movieService: MovieService, private route: ActivatedRoute){
}
checkRating(){
return typeof this.rating === 'number';
}
ngOnInit(){
this.route.params.subscribe(params => {
this.movieId = params.id;
var userId = localStorage.getItem('userId');
this.movieService.getMovie(this.movieId)
.subscribe(movie => {
this.movie = movie.obj;
this.movie.averageRating = Number(this.movie.averageRating);
console.log(this.movie);
});
if (userId){
this.movieService.getRating(userId, this.movieId)
.subscribe( result => {
this.rating = result.rating;
})
}
});
}
addRating(score) {
var userId = localStorage.getItem('userId');
this.movieService.addRating(score, userId, this.movie._id)
.subscribe(data => {
this.rating = data.obj.rating;
});
}
}
movie.component.html: this gives movie object to review.component through element app-review
<div class="container">
<div class="col col-md-4 col-md-offset-2">
<img [src]="movie?.pictureUrl" class="img-responsive" alt="hello">
</div>
<div class=" col col-md-6">
<h2>{{movie?.title}} ({{movie?.year}})</h2>
<h3>Average Score:</h3>
<span class="glyphicon glyphicon-star"></span><span><h1>{{movie?.averageRating}}</h1></span><br>
<h3>My Score:</h3>
<div class="row">
<div class="col">
<div *ngIf="!checkRating()" ngbDropdown class="d-inline-block">
<button class="btn btn-outline-primary" ngbDropdownToggle>Rate The Movie!</button>
<div ngbDropdownMenu aria-labelledby="dropdownBasic1">
<button value="1" (click)="addRating(1)" class="dropdown-item">1</button>
<button value="2" (click)="addRating(2)" class="dropdown-item">2</button>
<button value="3" (click)="addRating(3)" class="dropdown-item">3</button>
<button value="4" (click)="addRating(4)" class="dropdown-item">4</button>
<button value="5" (click)="addRating(5)" class="dropdown-item">5</button>
</div>
</div>
<div *ngIf="checkRating()">
<h1>{{rating}}</h1>
</div>
</div>
</div>
<h4>{{movie?.director}}</h4>
<h4>{{movie?.actors}}</h4>
<h4>{{movie?.country}}</h4>
<p> {{movie?.description}}</p>
</div>
</div>
<hr class="col-md-8 col-md-offset-2">
<div class="col-md-8 col-md-offset-2">
<ng-container *ngIf="!!movie">
<app-review [movie]="movie"></app-review>
</ng-container>
</div>
review.component.ts
import {Component, ElementRef, Input, OnInit, ViewChild} from "#angular/core";
import {NgForm} from "#angular/forms";
import {ReviewService} from "./review.service";
import {ActivatedRoute} from "#angular/router";
#Component({
selector: 'app-review',
templateUrl: './review.component.html',
styleUrls: ['./review.component.css']
})
export class ReviewComponent implements OnInit{
movieId;
#Input('movie') movie;
#ViewChild('textArea') textArea;
constructor(private reviewService: ReviewService, private route: ActivatedRoute){}
ngOnInit(){
this.route.params.subscribe( params => {
this.movieId = params.id
});
};
onClear(form: NgForm) {
form.resetForm()
}
onSubmit(form: NgForm) {
let content = form.value.review;
let userId = localStorage.getItem('userId');
let movieId = this.movieId;
this.reviewService.addReview(content, userId, movieId)
.subscribe( result => {
console.log(result.obj);
this.movie.reviews.unshift(result.obj);
form.resetForm()
})
}
}
review.component.html: this gives movie object to the review-list component through app-review-list
<ng-container *ngIf="!!movie">
<app-review-list [movie]="movie"></app-review-list>
</ng-container>
<hr>
<form ngNativeValidate (ngSubmit)="onSubmit(f)" #f="ngForm">
<div class="form-group">
<label for="review">Write A Review:</label>
<textarea
#textArea
(keyup.enter)="onSubmit(f)"
rows="4"
cols="50"
type="text"
id="review"
ngModel
class="form-control"
name="review"
required
></textarea>
</div>
<button type="button" class="btn btn-danger" (click)="onClear(f)">Clear</button>
<button class="btn btn-primary" type="submit">Save</button>
</form>
you can access it in ngOnInit() just implement OnInit interface

Particles.js no particles are loaded in angular

I have added particles.js to an Angular 4 project like mentioned here
Json file is being loaded but I don't see particles on screen
In .ts component :
import { Component, Output, ViewEncapsulation, OnInit } from '#angular/core';
import { MnFullpageOptions, MnFullpageService } from 'ngx-fullpage';
declare var particlesJS: any;
#Component({
selector: 'app-root',
encapsulation: ViewEncapsulation.None,
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
title = 'app';
#Output() public options: MnFullpageOptions = new MnFullpageOptions({
autoScrolling: true,
controlArrows: false,
});
ngOnInit() {
particlesJS.load('particles-js', 'assets/particlesjs-config.json', console.log('callback - particles.js config loaded'));
}
constructor() { }
}
Html file :
<div id="particles-js" style="border:2px solid black; background-color:red">
<div class="menu-wrapper">
</div>
<div id="content-wrapper" [mnFullpage]="options" [mnFullpageNavigation]="true" [mnFullpageKeyboardScrolling]="true" [mnFullpageSlidesNavigation]="true" mnFullpageSlidesNavPosition="bottom">
<div class="section welcome-section fp-section fp-table ">
<div class="fp-tableCell ">
<div id="presentation" class="example-card" fxLayout="row">
<app-slide-presentation>
</app-slide-presentation>
</div>
</div>
</div>
<div class="section welcome-section fp-section fp-table">
<div class="fp-tableCell">
<div id="formation" class="example-card" fxLayout="row" fxLayoutAlign="center center">
<app-formation>
</app-formation>
</div>
</div>
</div>
<div class="section welcome-section fp-section fp-table">
<div fxLayout="row" class="fp-tableCell " style="height:100%; width:60%; overflow:hidden; margin:auto ; background-color:white ">
<div class="slide" >
<app-competences1>
</app-competences1>
<div class="slide" style="background-color:white">
>
</div>
<div class="slide">
</div>
<div class="slide">
</div>
<div class="slide">
</div>
</div>
</div>
</div>
</div>
</div>
In console I get callback message :
callback - particles.js config loaded
I have initiated a new project where everything is being working :
in ts component file :
import { Component, Input, Output, OnInit, ViewEncapsulation } from '#angular/core';
declare var particlesJS: any;
#Component({
selector: 'app-root',
encapsulation: ViewEncapsulation.None,
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
title = 'app';
ngOnInit() {
particlesJS.load('particles-js', 'assets/particlesjs-config.json', null);
}
}
in html :
<div id="particles-js"></div>
particles are loading perfectly.
I don't see the difference between 2 examples.
Adding "background-color" to 'particles-js' container worked for me.
#home.component.html:
<div id="particles-js"></div>
#home.component.scss:
#particles-js {
height: 100vh;
background-color: black;
}

how to use single Modal dialog Component to show different data or message in Angular 2

I am working on application in Angular 2 and fairly new to it. I want to display Modal dialog on click of a Card. I have integrated angular material Modal popup in my app as instructed in this tutorial. Each of card have different Data and that data i want to display on same modal popup.
My Modal Component is :
import { Component, OnInit } from '#angular/core';
import { MdDialogRef } from '#angular/material';
#Component({
selector: 'confirm-dialog',
template: `
<p>{{ title }}</p>
<p>{{ message }}</p>
<button type="button" md-raised-button
(click)="dialogRef.close(true)">OK</button>
<button type="button" md-button
(click)="dialogRef.close()">Cancel</button>
`,
})
export class ModalComponent {
public title: string;
public message: string;
constructor(public dialogRef: MdDialogRef<ModalComponent>) {
}
}
my Card component is :
import { Component, OnInit } from '#angular/core';
import { ModalService } from '../services/modal.service';
#Component({
selector: 'app-content',
templateUrl: './content.component.html',
styleUrls: ['./content.component.css']
})
export class ContentComponent implements OnInit {
private solutions: Array<Object>;
public result: any;
constructor(public dialogsService: ModalService) {
}
public openDialog() {
this.dialogsService
.confirm('Confirm Dialog', 'Are you sure you want to do this?')
.subscribe(res => this.result = res);
}
ngOnInit() {
}
}
and HTML is :
<div class="container self-card-container">
<div class="row lab-work">
<div class="col-12 col-sm-4 col-md-4 col-lg-4 col-xl-4">
<div class="custom-card">
<div class="card-header whatWeDo align-item-center">
<div class="custom-header-image mat-card-avatar d-flex justify-content-center align-self-center" md-card-avatar="">
<img src="./assets/what-we-do.png" class="align-self-center">
</div>
<div class="custom-header-text d-flex align-self-center">
<div class="custom-card-title">What We Do</div>
</div>
</div>
<div class="custom-card-content">
Co-Innovate with customers and partners in a "sandbox" environment to develop proof of concepts. Harness Emerging technologies
to come up with newer solutions around existing problems. Provide an Immersive Experience to our customers of potential
solutions for feel and function.
</div>
<div class="custom-card-action align-items-center">
<button md-button class="read-more" (click)="openDialog()">Read More</button>
</div>
</div>
</div>
<div class="col-12 col-sm-4 col-md-4 col-lg-4 col-xl-4">
<div class="custom-card">
<div class="card-header howWeDo align-item-center">
<div class="custom-header-image mat-card-avatar d-flex justify-content-center align-self-center" md-card-avatar="">
<img src="./assets/how-we-do.png" class="align-self-center">
</div>
<div class="custom-header-text d-flex align-self-center">
<div class="custom-card-title">How We Do</div>
</div>
</div>
<div class="custom-card-content">
We begin with problem identification followed by ideation phase to create an alternate point of view on the problem. This
is followed by building a proof of concept or a prototype which is then handed over to customer for feedback. The
whole process is repeated iteratively as desired.
</div>
<div class="custom-card-action align-items-center">
<button md-button class="read-more" (click)="openDialog()">Read More</button>
</div>
</div>
</div>
<div class="col-12 col-sm-4 col-md-4 col-lg-4 col-xl-4">
<div class="custom-card">
<div class="card-header howWeDone align-item-center">
<div class="custom-header-image mat-card-avatar d-flex justify-content-center align-self-center" md-card-avatar="">
<img src="./assets/how-things-get-done.png" class="align-self-center">
</div>
<div class="custom-header-text d-flex align-self-center">
<div class="custom-card-title">How Things Get Done</div>
</div>
</div>
<div class="custom-card-content">
We follow 'continuous flow' based development as opposed to traditional software development life-cycle to stay lean. An
integrated application life cycle management gives us necessary agility and transparency.
</div>
<div class="custom-card-action align-items-center">
<button md-button class="read-more" (click)="openDialog()">Read More</button>
</div>
</div>
</div>
</div>
Dialog Service is :
import { Observable } from 'rxjs/Rx';
import { ModalComponent } from '../modal/modal.component';
import { MdDialogRef, MdDialog, MdDialogConfig } from '#angular/material';
import { Injectable } from '#angular/core';
#Injectable()
export class ModalService {
constructor(private dialog: MdDialog) { }
public confirm(title: string, message: string): Observable<boolean> {
let dialogRef: MdDialogRef<ModalComponent>;
dialogRef = this.dialog.open(ModalComponent);
dialogRef.componentInstance.title = title;
dialogRef.componentInstance.message = message;
return dialogRef.afterClosed();
}
}
I want to display title and message of card on modal that is being clicked.
How to pass Data respective to card in Modal?
Pass the title and message as parameters to the openDialog() method, eg.
html:
<button md-button class="read-more" (click)="openDialog('My special title', 'My special message')">Read More</button>
component:
public openDialog(title: string, message: string) {
this.dialogsService
.confirm(title, message)
.subscribe(res => this.result = res);
}
EDIT based on question in comment:
The quick and easy way would be to add the message content as string properties of the component and pass these as the parameters, eg.
In component:
export class ContentComponent implements OnInit {
private solutions: Array<Object>;
public result: any;
public dialogOneMessage = `<p>Stuff</p><p>More stuff<p><img src=:/photo.jpg" />
html:
<button md-button class="read-more" (click)="openDialog('My special title', dialogOneMessage)">Read More</button>
I don't really like this approach though - not a good separation of concerns having large amounts of html as component properties. If you have large amounts of complex data for each custom dialog you are probably better off creating a custom component for each of your dialogs and pass your custom component to the this.dialog.open() instead reusing the ConfirmDialog component.

Categories