0

I'm still somewhat new to Angular development.

I'm building a website for a construction company, where I'm using three different components on one page. Here's a basic outline of what the page currently has, and what I want it to do:

  • The projects component contains a list of projects on the right side of the page. Out of all those projects, the one that is selected shows up on the left side of the page (projectdetail.component.html)

  • The user may click on any of the projects on the right side of the page to change the selected project. This new one will show up on the left side of the page in projectdetail.component.html

  • In the projectdetail component, there is a mini gallery of other images that the user can click on in order to change the main image that displays (like a typical photo slideshow).

  • THE PROBLEM I'M HAVING RIGHT NOW: The main image in projectdetail.component no longer changes whenever I click on any of the projects in the right panel (all of the other data, including the address, images in the slideshow, etc. do update as they should); they only time it changes is when I click on any of the images in the gallery in the projectdetail component. A solution I've proposed is to try to make updates to 'mainImage' (See code below) whenever you click on a project on the right panel, which it does not do. I am not sure how to accomplish this.

here is an illustration; only the images in the gallery update the main one, but I want the main image to update when clicking on any of the photos on the right to the photo that is shown in that project

My Project class:

export class Project {
    id: number;
    address: string;
    images: string[];
    price: string;
    featured: boolean;
    description: string;
}

My Project Service:

import { Injectable } from '@angular/core';
import { Project } from '../shared/project';
import { PROJECTS } from '../shared/projects';

@Injectable()

export class ProjectService {

  constructor() { }

  getProjects(): Project[] {
    return PROJECTS;
  }

  getProject(id: number): Project {
    return PROJECTS.filter((project) => (project.id === id))[0];
  }

}

Not including one of the components, which is irrelevant to the question, they are as follows:

projects.component.html

<div class="container"
  fxLayout.sm="row"
  fxLayout.xs="column">  

  <div fxFlex=60>
    <app-projectdetail [project]="selectedProject" ></app-projectdetail> 
  </div> 

  <div fxFlex=40 *ngIf="projects">
    <mat-grid-list cols="1" rowHeight="300px">
      <mat-grid-tile *ngFor="let project of projects" (click)="onSelect(project)">
        <img src="{{ project.images[0] }}">
        <mat-grid-tile-footer>
          <h1 mat-line ngDefaultControl>{{ project.address | uppercase }}</h1>
        </mat-grid-tile-footer>
      </mat-grid-tile>
    </mat-grid-list>
  </div>
</div>

projects.component.ts

import { Component, OnInit, Inject, Optional } from '@angular/core';
import { MatDialog } from '@angular/material';

import { ProjectDialogComponent } from '../project-dialog/project-dialog.component';

import { Project } from '../shared/project';
import { ProjectService } from '../services/project.service';

@Component({
  selector: 'app-projects',
  templateUrl: './projects.component.html',
  styleUrls: ['./projects.component.scss']
})

export class ProjectsComponent implements OnInit {
  projects: Project[];
  selectedProject: Project;
  image: String;
  mainImage: String;

  constructor(private projectService: ProjectService, private dialog: MatDialog) { }

  ngOnInit() {
    this.projects = this.projectService.getProjects();
    this.selectedProject = this.projectService.getProject(0);
  }

  onSelect(project: Project) {
    this.selectedProject = project;
    this.mainImage = project.images[0];
  }

}

projectdetail.component.html

<div class="container"
  fxLayout="row"
  fxLayoutGap="10px">

  <div fxFlex=100>
    <mat-card *ngIf="project">
      <img src="{{ mainImage }}" (click)="openDialog(project)">
      <mat-card-header>
        <mat-card-title><h1>{{ project.address | uppercase }}</h1></mat-card-title>
      </mat-card-header>
      <div id="preWrapper">
        <div id="imageWrapper">
          <div id="imageContainer" *ngFor="let image of project.images">
            <img src="{{ image }}" (click)="changeImage(image)" />
          </div>
        </div>
      </div>
      <mat-card-content>
        <p>{{ project.description }}</p>
      </mat-card-content>
    </mat-card>
  </div>
</div>

projectdetail.component.ts

import { Component, OnInit, Inject, Input } from '@angular/core';
import { MatDialog } from '@angular/material';

import { ProjectDialogComponent } from '../project-dialog/project-dialog.component';

import { Project } from '../shared/project';
import { ProjectService } from '../services/project.service';

@Component({
  selector: 'app-projectdetail',
  templateUrl: './projectdetail.component.html',
  styleUrls: ['./projectdetail.component.scss']
})
export class ProjectdetailComponent implements OnInit {

  @Input()
  project: Project;
  projects: Project[];
  selectedProject: Project;
  image: String;
  mainImage: String;

  constructor(private projectService: ProjectService, private dialog: MatDialog) { }

  ngOnInit() { 
    this.mainImage = this.projectService.getProject(0).images[0];
  }

  openDialog(project: Project): void {
    let dialogRef = this.dialog.open(ProjectDialogComponent, {
      data: {
        address: this.project.address,
        images: this.project.images
      }
    })
  }

  changeImage(image: String) {
    this.mainImage = image;
  }

}
7
  • so your issue is when you do change on main component , then detail component doesnt change ? Commented May 3, 2018 at 6:30
  • The detail component changes; but the main image does not. I'll update my post to make that more clear. Commented May 3, 2018 at 6:30
  • so if project change in main page then it changing detail component but you main page image is not changing Commented May 3, 2018 at 6:31
  • @PranayRana - Yes Commented May 3, 2018 at 6:32
  • added my answer , but where is code for you main page component Commented May 3, 2018 at 6:39

1 Answer 1

2

you write ngOnChange event in you detail component and then raise event for changing image in you main page ,

 ngOnChanges(changes: SimpleChanges) {
    for (let propName in changes) {  
        if (propName === 'project') {
           Promise.resolve(null).then(() => 
                {raise event or write code toc hange main page image});
        }
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

Hey, just tried this now... yes, it worked!!! In the code to change the main page image, I simply put {this.mainImage = this.project.images[0]}. Thank you Pranay!! I'll have to read more in to ngOnChanges and some of the other angular functions.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.