টাইপস্ক্রিপ্ট সহ অ্যাঙ্গুলার 2 এ এইচটিপি ডেটা থেকে আরএক্সজেএস পর্যবেক্ষণগুলি শৃঙ্খলাবদ্ধ


99

আমি বর্তমানে AngularJS 1 এর সাথে সুখে কাজ করার পরে নিজেকে Angular2 এবং TypeScript শেখানোর চেষ্টা করছি! * গত 4 বছর ধরে! আমাকে স্বীকার করতে হবে যে আমি এটি ঘৃণা করছি তবে আমি নিশ্চিত যে আমার ইউরেকার মুহূর্তটি ঠিক কোণার কাছাকাছি ... যাইহোক, আমি আমার ডামি অ্যাপ্লিকেশনটিতে একটি পরিষেবা লিখেছি যা ফোনি ব্যাকএন্ড থেকে http ডেটা আনবে আমি লিখেছি যে জেএসএনকে পরিবেশন করে।

import {Injectable} from 'angular2/core';
import {Http, Headers, Response} from 'angular2/http';
import {Observable} from 'rxjs';

@Injectable()
export class UserData {

    constructor(public http: Http) {
    }

    getUserStatus(): any {
        var headers = new Headers();
        headers.append('Content-Type', 'application/json');
        return this.http.get('/restservice/userstatus', {headers: headers})
            .map((data: any) => data.json())
            .catch(this.handleError);
    }

    getUserInfo(): any {
        var headers = new Headers();
        headers.append('Content-Type', 'application/json');
        return this.http.get('/restservice/profile/info', {headers: headers})
            .map((data: any) => data.json())
            .catch(this.handleError);
    }

    getUserPhotos(myId): any {
        var headers = new Headers();
        headers.append('Content-Type', 'application/json');
        return this.http.get(`restservice/profile/pictures/overview/${ myId }`, {headers: headers})
            .map((data: any) => data.json())
            .catch(this.handleError);
    }

    private handleError(error: Response) {
        // just logging to the console for now...
        console.error(error);
        return Observable.throw(error.json().error || 'Server error');
    }   
}

এখন কোন অংশে আমি উভয় getUserInfo()এবং getUserPhotos(myId)পদ্ধতি চালাতে (বা চেইন) করতে চাই । অ্যাঙ্গুলারজেএসে এটি সহজ ছিল যেমনটি আমার নিয়ামক হিসাবে আমি "ডুমের পিরামিড" এড়াতে এই জাতীয় কিছু করতাম ...

// Good old AngularJS 1.*
UserData.getUserInfo().then(function(resp) {
    return UserData.getUserPhotos(resp.UserId);
}).then(function (resp) {
    // do more stuff...
}); 

এখন আমি আমার উপাদানগুলিতে অনুরূপ কিছু করার চেষ্টা করেছি (পরিবর্তিত .thenকরে .subscribe) তবে আমার ত্রুটি কনসোলটি পাগল হয়ে যাচ্ছে!

@Component({
    selector: 'profile',
    template: require('app/components/profile/profile.html'),
    providers: [],
    directives: [],
    pipes: []
})
export class Profile implements OnInit {

    userPhotos: any;
    userInfo: any;

    // UserData is my service
    constructor(private userData: UserData) {
    }

    ngOnInit() {

        // I need to pass my own ID here...
        this.userData.getUserPhotos('123456') // ToDo: Get this from parent or UserData Service
            .subscribe(
            (data) => {
                this.userPhotos = data;
            }
        ).getUserInfo().subscribe(
            (data) => {
                this.userInfo = data;
            });
    }

}

আমি স্পষ্টতই কিছু ভুল করছি ... আমি কীভাবে পর্যবেক্ষক এবং আরএক্সজেএস দিয়ে সেরা করব? দুঃখিত যদি আমি বোকা প্রশ্ন জিজ্ঞাসা করি ... তবে আগাম সহায়তার জন্য ধন্যবাদ! আমার HTTP শিরোনামগুলি ঘোষণার সময় আমি আমার ফাংশনগুলিতে পুনরাবৃত্ত কোডটি লক্ষ্য করেছি ...

উত্তর:


141

আপনার ব্যবহারের ক্ষেত্রে, আমি মনে করি flatMapঅপারেটরটি আপনার যা প্রয়োজন:

this.userData.getUserPhotos('123456').flatMap(data => {
  this.userPhotos = data;
  return this.userData.getUserInfo();
}).subscribe(data => {
  this.userInfo = data;
});

এইভাবে, আপনি প্রথম অনুরোধটি পাওয়ার পরে দ্বিতীয় অনুরোধটি কার্যকর করবেন। flatMapযখন আপনি আগের অনুরোধ (পূর্ববর্তী ইভেন্ট) ফল ব্যবহার করতে অন্য একটি চালানো চান অপারেটর বিশেষ করে দরকারী। অপারেটরটি এটি ব্যবহার করতে সক্ষম করতে আমদানি করতে ভুলবেন না:

import 'rxjs/add/operator/flatMap';

এই উত্তর আপনাকে আরও বিশদ দিতে পারে:

আপনি যদি কেবল subscribeপদ্ধতি ব্যবহার করতে চান তবে আপনি এর মতো কিছু ব্যবহার করুন:

this.userData.getUserPhotos('123456')
    .subscribe(
      (data) => {
        this.userPhotos = data;

        this.userData.getUserInfo().subscribe(
          (data) => {
            this.userInfo = data;
          });
      });

শেষ করতে, যদি আপনি উভয় অনুরোধকে সমান্তরালভাবে সম্পাদন করতে চান এবং সমস্ত ফলাফল তখনই জানানো হয়, আপনার ব্যবহারের কথা বিবেচনা করা উচিত Observable.forkJoin(আপনার যুক্ত করতে হবে import 'rxjs/add/observable/forkJoin'):

Observable.forkJoin([
  this.userData.getUserPhotos(),
  this.userData.getUserInfo()]).subscribe(t=> {
    var firstResult = t[0];
    var secondResult = t[1];
});

তবে আমি ত্রুটিটি পেয়েছি 'TypeError: উত্স.সউসক্রাইব [নাল]' তে কোনও ফাংশন নয়
মাইক সাভ

আপনার কোথায় এই ত্রুটি আছে? ফোন করার সময় this.userData.getUserInfo()?
থিয়েরি টেম্পিলার

4
উহু! আমার উত্তরে একটি টাইপো ছিল: this.userData.getUserPhotos(), this.userData.getUserInfo()পরিবর্তে this.userData.getUserPhotos, this.userData.getUserInfo()। দুঃখিত!
থিয়েরি টেম্পিলার

4
ফ্ল্যাটম্যাপ কেন? সুইচম্যাপ কেন নয়? আমি ধরে নেব যে প্রাথমিক জিইটি অনুরোধটি হঠাৎ ব্যবহারকারীর জন্য অন্য মান আউটপুট করে দেয়, আপনি ব্যবহারকারীর আগের মানটির জন্য চিত্রগুলি পেতে থাকবেন না
f.khantsis

4
যে কেউ এটি দেখার জন্য এবং ভাবছেন কেন এটি কাজ করছে না: আরএক্সজেএস 6 এ আমদানি এবং কাঁটাচামচ সিনট্যাক্সটি কিছুটা পরিবর্তন হয়েছে। import { forkJoin } from 'rxjs';ফাংশনটি আমদানি করার জন্য আপনাকে এখন যুক্ত করতে হবে। এছাড়াও, ফোর্কজাইন এখন পর্যবেক্ষণযোগ্য সদস্য নয়, একটি পৃথক ফাংশন। পরিবর্তে Observable.forkJoin()এটি ঠিক forkJoin()
বাস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.