3

I wanted to bind a value from my component ImageDetail to the component ImageComment like

ImageDetailHtml:

<image-comment [photo]="photo"></image-comment>

ImageCommentComponent:

export class ImageCommentComponent {
  @Input('photo') photo: Photo;

and show this values into my ImageCommentHtml:

  <h3>{{user.userName}}</h3>
  <h4>{{photo.title}}</h4>
  <p>{{photo.description}}</p>

The problem is, that the data of the photo is loaded after building the ImageCommentHtml and i don't get the values. Any ideas orexamples how i can solve this async problem? I tried very much out and nothing worked.

Is there a opportunity to load the child component later?

** UPDATE ** Tried the solution:

<image-comment *ngIf="photo" [photo]="photo"></image-comment>

and it still doesn't work. I added a few loggers:

  ngAfterViewChecked() {
    console.log("After view checked: " + 'photo', this.photo)
  }

  ngOnInit() {
    console.log("On Init: " + 'photo', this.photo)
  }

and the result is:

On Init: photo Photo {}
image-comment.component.ts:42 After view checked: photo Photo {}
image-comment.component.ts:42 After view checked: photo Photo {}
image-comment.component.ts:42 After view checked: photo Photo {}
image-comment.component.ts:42 After view checked: photo Photo {}
image-comment.component.ts:42 After view checked: photo Photo {}
image-comment.component.ts:42 After view checked: photo Photo {}
image-comment.component.ts:42 After view checked: photo Photo {}
image-comment.component.ts:42 After view checked: photo Photo {}
image-comment.component.ts:42 After view checked: photo Photo {}
image-comment.component.ts:42 After view checked: photo Object {photoId: 4, photoName: "#love", photoTitle: "me", photoDescription: null, imageName: "Unbenannt.PNG"…}

So it is still loading to late :( ImageDetailComponent

  //COMPONENTS
    import {Component} from '@angular/core';
    import {Router, ActivatedRoute, Params}    from '@angular/router';
    import {ImageCommentComponent} from './image-comment.component.ts'
    //SERVICES
    import {UserService} from '../services/user.service';
    import {PhotoService} from '../services/photo.service';
    //MODELS
    import {User} from '../models/user.model';
    import {Photo} from '../models/photo.model';
    //SETTINGS
    import {LocalStorageSettings} from '../properties/localstorage.properties';

    @Component({
      selector: 'image-detail',
      templateUrl: 'app/components/image-detail.component.html',
      providers: [PhotoService,UserService]
    })

    export class ImageDetailComponent {
      photo: Photo = new Photo();
      like: string;
      user: User;
      imageUrl: string;



      constructor(
        private photoService: PhotoService,
        private userService: UserService,
        private route: ActivatedRoute
      ) {
        let photoId: any;
        this.route.params.forEach((params: Params) => {
          photoId = +params['id'];
        });
        this.photoService.getPhotoByPhotoId(photoId).subscribe(
          photo => {
            this.photo = JSON.parse(JSON.parse(JSON.stringify(photo))._body);
            this.imageUrl = "http://localhost:8080/images/" + this.photo.imageName;

            this.userService.getUserByName(`${LocalStorageSettings.getLocalUsername}`).subscribe(
              user => {
                this.user = JSON.parse(JSON.parse(JSON.stringify(user))._body);
                if(this.user.likedPhotoList.filter(photo => photo.photoId == this.photo.photoId)[0]) {
                  this.like="Unlike";
                } else {
                  this.like="Like";
                }
              },
              error => console.log(error)
            )
          },
          error => console.log(error)
        )
      }

      goBack() {
        window.history.back();
      }

      likeDisplay() {
        if(this.like == "Like") {
          this.like = "Unlike";
          this.user.likedPhotoList.push(this.photo);
          this.photo.likes+=1;
          this.userService.updateUser(this.user).subscribe();
          this.photoService.updatePhoto(this.photo).subscribe();
        } else {
          this.like = "Like";
          for(let i = 0; i < this.user.likedPhotoList.length; i++) {
            if(this.user.likedPhotoList[i].photoId == this.photo.photoId) {
              this.user.likedPhotoList.splice(i,1);
            }
          }

          this.photo.likes-=1;
          this.userService.updateUser(this.user).subscribe();
          this.photoService.updatePhoto(this.photo).subscribe();
        }
      }
    }

ImageDetailHtml:

<div class="pusher">
  <div class="ui inverted vertical segment">
    <div class="ui text container">
      <div class="center aligned">
        <img src="{{imageUrl}}" class="ui image  centered" />
      </div>
      <br>
      <div class="ui grid">
          <div class="left floated six wide column" style="cursor:pointer; color:grey;">
            <span (click)="goBack()"><i class="long arrow left icon">Back</i> </span>
          </div>
          <div class="left floated ten wide column right aligned" style=" color:grey;">
            <i class="thumbs outline up icon"></i>{{photo.likes}} &nbsp;&nbsp;&nbsp;
            <a style="cursor: pointer" (click)="likeDisplay()">{{like}}</a>
          </div>
      </div>
    </div>
  </div>
</div>
<image-comment *ngIf="photo" [photo]="photo"></image-comment>

ImageCommentComponent:

    //COMPONENTS
import {Component} from '@angular/core';
//MODELS
import {User} from '../models/user.model';
import {Photo} from '../models/photo.model';
// SERVICES
import {UserService} from '../services/user.service';
import {AddPhotoService} from '../services/add-photo.service';
import {UploadPhotoService} from '../services/upload-photo.service';
// SETTINGS
import {LocalStorageSettings} from '../properties/localstorage.properties';

@Component({
  selector: 'add-photo',
  providers: [UploadPhotoService, AddPhotoService],
  templateUrl: 'app/components/add-photo.component.html'
})
export class AddPhotoComponent {
  newPhoto: Photo = new Photo();
  photoAdded: boolean = false;
  user: User;

  constructor (
    private uploadPhotoService: UploadPhotoService,
    private addPhotoService: AddPhotoService,
    private userService: UserService
  ) {}

  onSubmit() {
    var userName: string = localStorage.getItem(`${LocalStorageSettings.LOCAL_STORAGE_USERNAME}`);
    this.userService.getUserByName(userName).subscribe(
      user => {
        this.user = JSON.parse(JSON.parse(JSON.stringify(user))._body);
        console.log(this.user);
        this.newPhoto.user = this.user;
        this.addPhotoService.sendPhoto(this.newPhoto).subscribe(
          data => {
            this.photoAdded = true;
            this.newPhoto = new Photo();
          },
          error => console.log(error)
        )
      },
      error => console.log(error)
    )
  }
}

ImageComponentHtml:

<div class="ui text container">
  <h3>{{user.userName}}</h3>
  <h4>{{photo?.title}}</h4>
  <p>{{photo?.description}}</p>

  <div class="ui comments">
    <h3 class="ui dividing header">Comments</h3>

    <div class="comment" *ngFor="let comment of photo.commentList">
      <div class="ui grid">
        <div class="two wide column">
          <img src="http://localhost:8080/pic/avatar1.png" class="ui image tiny">
          <span class="author">{{photoComment.userName}}</span>
        </div>
        <div class="fourteen wide column">
          <div class="ui blue message">
            <div class="content">
              <div class="text">
                {{photoComment.content}}
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
    <br>
    <div class="ui grid">
      <div class="two wide column">
        <img src="http://localhost:8080/pic/avatar1.png" class="ui image tiny">
        <span class="author">{{user.userName}}</span>
      </div>
      <div class="fourteen wide column">
        <form class="ui form" (ngSubmit)="onSubmit()" #commentForm="ngForm">
          <div class="field">
            <textarea #words rows="3" placeholder="Add a comment" required [(ngModel)]="photoComment.content" name="photoCommentContent"></textarea>
          </div>
          <button type="submit" class="ui red button">Comment</button>
        </form>
      </div>
    </div>
  </div>
</div>
1
  • 1
    You should be checked data of the photo and make sure data is loaded. Commented Sep 20, 2016 at 7:55

1 Answer 1

1

You could use *ngIf directive to make ImageCommentComponent load only after variable photo receives data, not before:

<image-comment *ngIf="photo" [photo]="photo"></image-comment>

Edit:

Problem lies in your ImageDetailComponent - you initialize variable photo:

photo: Photo = new Photo();

You should only declare it, like this:

photo: Photo;

This way, value of photo will be undefined and ImageCommentComponent won't load until photo receives data.

Sign up to request clarification or add additional context in comments.

5 Comments

thanks your your fast reply! Still doesn't work :( I added the logs from the browser and the code of this two components and htmls.
@Keshtocal I found error and explained how to fix it, check my post again.
Hey Stefant, thank you!!! Now i get the values at OnInit! :))) Thank you so much! Now I just have to find out why I'm getting it as "Object" and not as "Photo"-Model.
@Keshtocal You should get it as Object because that's what it is. Every custom data type that you make is considered as Object. Try to print User in console for example, you will see that it is Object as well. By the way, consider marking my answer as accepted by clicking the check-mark so people with similar problems will know that this solution is good. Cheers.
Thank you for your explanation. You're totally right. I marked it as accepted. Have a nice day.

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.