2016-08-09 3 views
1

У меня есть то, что я считал довольно простой настройкой. Я создаю профиль пользователя в компоненте ввода профиля. Затем После отправки формы и создания пользователя я хочу отправить пользователя в компонент-img-upload для добавления фотографии. Я понимаю, что это имело бы смысл, если бы сохранить созданный профиль в службе профиля, а затем вызвать этот профиль в компоненте img-upload. Но у меня что-то не хватает, потому что, когда я добираюсь до компонента img-upload console.log (this.profile), профиль всегда равен нулю.Angular2 Subscription всегда подходит null

Я чувствую, что я неправильно понимаю что-то очень важное для подписки и наблюдаемых здесь. Все, что я хочу сделать, это создать объект Profile на первом компоненте, а затем передать созданный профиль второму компоненту, чтобы затем загрузить фотографию и назначить ее профилю.

Может кто-нибудь, пожалуйста, помогите мне понять, что мне здесь не хватает?

профиль-input.component

import... 

@Component({ 
    moduleId: module.id, 
    selector: 'my-profile-input', 
    templateUrl: 'profile-input.template.html', 
    directives: [REACTIVE_FORM_DIRECTIVES] 
}) 

export class ProfileInputComponent implements OnInit { 
@Output() profile: Profile; 
profile: Profile = null; 

constructor(private formBuilder:FormBuilder, 
      private profileSrevice: ProfileService, 
      private errorService: ErrorService, 
      private router: Router, 
      private route: ActivatedRoute) {} 

onSubmit() { 
const profile: Profile = new Profile(
      this.profileForm.value.first_name, 
      this.profileForm.value.last_name 
); 

this.profileSrevice.addProfile(profile) 
      .subscribe(
       data => { 
        console.log('what comes back from addProfile is: ' + JSON.stringify(data)); 
        this.profileSrevice.profiles.push(data); 

        // The line below will superceded the one above. 
        this.profileSrevice.pushData(data); 
       }, 
       error => this.errorService.handleError(error) 
      ); 
     this.router.navigate(['profile-img-upload', {myProfile: this.profile}]); 
} 

profile.service.ts

import... 

@Injectable() 
export class ProfileService { 
    pushedData = new EventEmitter<Profile>(); 

    pushData(value: Profile) { 
    this.pushedData.emit(value); 
    console.log('value in service is '); 
    console.log(value); 
    } 
} 

профиль-IMG-upload.component.ts

import... 

@Component({ 
moduleId: module.id, 
selector: 'my-profile-img-upload', 
templateUrl: 'profile-img-upload.template.html', 
directives: [ ROUTER_DIRECTIVES, FILE_UPLOAD_DIRECTIVES, NgClass, NgStyle, CORE_DIRECTIVES, FORM_DIRECTIVES ], 
providers: [AWSUploadService, UploadFileService] 
}) 

export class ProfileImgUploadComponent implements OnInit { 
    @Input() myProfile: Profile; 
    profile: Profile; 

    constructor(private uploadFileService: UploadFileService, 
      private route: ActivatedRoute, 
      private profileService: ProfileService, 
      private errorService: ErrorService) { 
    this.filesToUpload = [];} 

    ngOnInit() { 
    this.profileService.pushedData.subscribe(
     (value: Profile) => this.profile 
    ); 

    console.log("this.profile in img upload is"); 
    console.log(this.profile); 
    } 
} 

ответ

0

Вопрос у меня был был из-за непонимания того, как использовать наблюдаемыми. Я перенаправлялся на другую страницу (перезагружая новый шаблон новым компонентом), чтобы получить данные профиля в область, где я хотел загрузить изображения. Это была некорректная концепция. То, как я установил это должен был сделать следующее:

  1. Снять 2-й компонент и шаблон для загрузки и включать все, что код в компонент создания профиля

  2. Добавить некоторые заявления ngIf, чтобы определить, когда для отображения различных областей страницы создания профиля на основе пользователя, выполняющего различные задачи (например, ввод информации профиля и создание объекта профиля, добавление фотографии, добавление видео).

Делая эти вещи, я всегда был на той же странице, так что я мог бы сослаться на результаты 1 действия для использования в другой, и, как было достигнуто то, что я мог бы установить переменные для контроля состояния приложения и что было показано пользователю.

Окончательный код шаблона ниже:

<script src="profile-input.component.ts"></script> 
<section class="col-md-8 col-md-offset-2"> 
    <form [hidden]="formSubmitted" [formGroup]="profileForm" (ngSubmit)="onSubmit()"> 

    <div class="row"> 
     <div class="col-xs-12"> 
     <div class="form-group"> 
      <label for="first_name">First Name</label> 
      <input 
      type="text" 
      id="first_name" 
      class="form-control" 
      formControlName="first_name"> 
     </div> 
     </div> 
    </div> 
    <div class="row"> 
     <div class="col-xs-12"> 
     <div class="form-group"> 
      <label for="last_name">Last name</label> 
      <input 
      type="text" 
      id="last_name" 
      class="form-control" 
      formControlName="last_name"> 
     </div> 
     </div> 
    </div> 


    <div class="row"> 
     <label>UserType</label> 
     <input type="checkbox" id="producer" class="form-control" formControlName="producer" >Producer<br> 
     <input type="checkbox" id="client" class="form-control" formControlName="client" >Client<br> 
     <input type="checkbox" id="creative" class="form-control" formControlName="creative" >Creative<br> 
    </div> 


    <button type="submit" class="btn btn-primary" [disabled]="!profileForm.valid" >{{ !profile ? 'Add Profile' : 'Save Profile' }}</button> 
    <button type="button" class="btn btn-danger" (click)="onCancel()" *ngIf="profile">Cancel</button> 
    </form> 
</section> 

<!-- image upload START--> 
<section [hidden]="!imgUploadVisible" class="col-md-8 col-md-offset-2"> 
    <h2 *ngIf="createdProfile">Welcome {{createdProfile.first_name}}!</h2> 
    <p>Now lets get a look at you.</p> 
    <hr> 
    <h2>Profile Image Upload</h2> 
    <input type="file" (change)="imgFileChangeEvent($event)" placeholder="Upload file..." /> 
    <br> 
    <button type="button" (click)="uploadImg()">Upload Image</button> 
    <hr> 

    <div *ngIf="uploadFile" > 
    Uploaded File Path: {{ uploadFile }} 
    </div> 
    <div class="row"> 
    <div class="col-xs-12"> 
     <div class="img" *ngIf="uploadFile"> 
     <img [src]="uploadFile" width="200px" alt=""> 
     </div> 
    </div> 
    </div> 
    <br> 
    <button [hidden]="!uploadFile" type="button" (click)="sendToS3()">Send TO S3</button> 
    <hr> 
    <div *ngIf="s3LocString"> 
    S3 Location: {{s3LocString}} 
    <br> 
    <img [src]="s3LocString" width="200px" alt=""> 
    </div> 

    <button type="button" (click)="imgUploadComplete()">Next</button> 

</section> 
<!-- image upload END--> 


<!-- Video upload START--> 

<section [hidden]="!vidUploadVisible" class="col-md-8 col-md-offset-2"> 
    <h2>Upload Profile Video</h2> 
    <p>Now show us what you can do.</p> 
    <hr> 
    <h2>Demo Video Upload</h2> 
    <input type="file" (change)="vidFileChangeEvent($event)" placeholder="Upload file..." /> 
    <br> 
    <button type="button" (click)="uploadVid()">Upload Video</button> 
    <hr> 

    <div *ngIf="vidUploadFile" > 
    Uploaded File Path: {{ vidUploadFile }} 
    </div> 
    <div class="row"> 
    <div class="col-xs-12"> 
     <div class="vid" *ngIf="vidUploadFile"> 
     <video autoplay controls [src]="vidUploadFile"></video> 

     </div> 
    </div> 
    </div> 


</section> 

важные части профильного компонента ввода ниже:

uploadImg() { 
    console.log('this.createdProfile before upload'); 
    console.log(this.createdProfile); 
    this.uploadFileService.makeFileRequest("http://localhost:3000/upload", this.createdProfile.profileId, this.imgFilesToUpload, 'profileImg') 
     .subscribe(
     (result) => { 
      console.log('result in prof input action removed is'); 
      console.log(result); 
      this.imageUploaded = true; 
      this.formSubmitted = true; 
      this.uploadFile = result.obj.path; 
      this.uploadObject = result.obj 
     }, 
     (error) => { 
      console.log('We are in error'); 
      console.error(error); 
     }); 
    } 

    uploadVid() { 
    console.log('this.createdProfile before upload'); 
    console.log(this.createdProfile); 
    this.uploadFileService.makeFileRequest("http://localhost:3000/upload", this.createdProfile.profileId, this.vidFilesToUpload, 'profileVideo') 
     .subscribe(
     (result) => { 
      console.log('result in prof input action removed is'); 
      console.log(result); 
      this.vidUploaded = true; 
      this.vidUploadFile = result.obj.path; 
      this.vidUploadObject = result.obj 
     }, 
     (error) => { 
      console.log('We are in error'); 
      console.error(error); 
     }); 
    } 

    sendToS3() { 
    console.log('uploading to S3'); 
    console.log(this.uploadObject); 

    this.uploadFileService.sendToS3(this.uploadObject, this.createdProfile.profileId, this.uploadObject._id) 
     .subscribe(
     data => { 
      console.log(data); 
      this.s3Location = data; 
      this.s3LocString = data.Location; 
     }, 
     error => { 
      console.log(error); 
     } 
    ); 
    } 

Надеется, что это помогает кто-то еще, чтобы понять эти понятия лучше.

0

Вам нужно переместить код, который ссылается на данные, возвращаемые из подписки, в обратный вызов подписки. Эта функция вызывается, когда данные поступают из наблюдаемой

ngOnInit() { 
    this.profileService.pushedData.subscribe(
     (value: Profile) => { 
      this.profile = value; 
      console.log("this.profile in img upload is"); 
      console.log(this.profile); 
     }); 
    } 
} 
+0

Я пробовал это, когда я это делаю, я на самом деле никогда не вижу, чтобы журнал попадал на консоль, говоря «this.profile in img upload is» – JasonPerr

+0

Последний вывод, который попадает на консоль, является значением ** в сервисе ** а затем объект Profile (исходящий из метода profile.service pushData) – JasonPerr

+0

Трудно получить из нескольких фрагментов кода, что происходит на этапе выполнения. Вы должны знать, что данные доступны только после вызова callback. –