0

i need help in making this "view detail function" work. First, i had the users component which i want to imitate on how it worked. Like you have to access its service when you try to get the specific thing. But the users component is its not from coming from an api. Now, i want to imitate it in my news component which the details is coming from an api. How can i access the specific things details of the news component? I've put the code below both on the users component and news component.Thanks for the help.

user.service.ts

import { User } from './user.model';
import { Subject } from 'rxjs/Subject';
export class UserService {

usersChanged = new Subject<User[]>();

  private users: User[]= [
    new User('Harry', 'James', 99999889),
    new User('Thomas', 'Baker', 99638798)
  ];

  getUsers() {
    return this.users.slice();
  }

  getUser(index: number) {
    return this.users[index];
  }

user-list.component

import { Component, OnInit } from '@angular/core';
import { User } from '../user.model';
import { UserService } from '../user.service';
import { Router, ActivatedRoute } from '@angular/router';

@Component({
  selector: 'app-user-list',
  templateUrl: './user-list.component.html',
  styleUrls: ['./user-list.component.css']
})
export class UserListComponent implements OnInit {

  users: User[];
  index: number;

  constructor(private userService: UserService, private router: Router, private route: ActivatedRoute) { }

  ngOnInit() {
      this.users = this.userService.getUsers();
      this.userService.usersChanged
      .subscribe(
        (users: User[]) => {
          this.users = users;
        }
      );
  }

  onViewUserDetail(index: number){
    this.router.navigate(['users', index]);
  }

news.service.ts

import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders} from '@angular/common/http';
import 'rxjs/add/operator/map';

@Injectable()
export class NewsService {
    constructor(private httpClient: HttpClient) {
  }

getNews() {
    const authToken = localStorage.getItem('auth_token'); 
    const headers = new HttpHeaders() 
    .set('Content-Type', 'application/json') 
    .set('Authorization', `Bearer ${authToken}`);

    return this.httpClient
      .get('sample/news', { headers: headers })
      .map(
        (response => response));
}


getNewsDetail(index: number) {
    //
  }

news-list.component.ts

import { Component, OnInit } from '@angular/core';
import { NewsService } from '../news.service';
import { Router, ActivatedRoute } from '@angular/router';


@Component({
  selector: 'app-news-list',
  templateUrl: './news-list.component.html',
  styleUrls: ['./news-list.component.css']
})
export class NewsListComponent implements OnInit {
  newslists: any;
  constructor(private newsService: NewsService, private router: Router, private route: ActivatedRoute) { }

  ngOnInit() {

    this.newsService.getNews()
      .subscribe(
        (data:any) => {
          console.log(data);
          this.newslists = data.data.data;
          console.log(this.newslists);
        },
        error => {
          alert("ERROR");
        });
  }

  onViewNewsDetail(id: number){
    console.log(id);
    this.router.navigate(['news', id]);
  }

}

2 Answers 2

1

Didn't quite understand what the issue is. You are navigating to detail view onView***Detail() method. If you have defined your routes right, it should go to the respective component. And in that detail component ngOnInit() you can subscribe to the paramMap of the activated route and call the api or get the value from the store, however you want.

ngOnInit() {
        this.paramSubscription = this.route.paramMap
            .switchMap((params: ParamMap) => this.userService.getUser(+params.get('id')))
            .subscribe(
            res => {
                this.user= <User>res;
            },
            err => console.log('error retreiving user detail')
            )

    }

you will have the details in the user property in your detail component, and you can display it however you want it to be.

Update

To get detail for your news, you can create a news store with a behavior subject that will call you service to get all news - the list. your component can call this store as well. This store will expose getter of your private behavior subject which expose it as Observable.

Then you can access the subjects value at ny time by getValue() and don't have to call the api again for any view detail call. See example below:

    @Injectable()
    export class NewsStore {
        private _news: BehaviorSubject<List<News>> = new BehaviorSubject(List([]));

        constructor(
            private newsService: NewsService) {
            this.loadInititalData();
        }

        get news() {
            return this._news.asObservable();
        }

    getNews(id: number): any {
            return this._news.getValue().filter(news=> news.id == id);
        }

loadInititalData() {
        this.newsService.getAll()
            .subscribe(
            res => {
                let news= res;
                this._news.next(List(news))
            },
            err => this.handleError(err, "loadinitialdata")
            );
    }
    }
Sign up to request clarification or add additional context in comments.

9 Comments

I don't have issues with the user component. The user is an example which i want to follow. The User doesnt have an api. It just disappears after you refresh the page. my problem is on the news component. It works like this, if you click the news, it displays the news lists. In each newslists, there's a button called "View" which after clicked will display the details of that specific news. The Newslist is from api
so issue is in viewDetail() in the service?
Yes. ViewDetail() of the news component
So can i call the newslist from this NewsStore also because i'm calling the list of news from the service?
yes thats recommended. only store should call the service, rest all components should call the store. You can subscrive to news from the store as it's an observable. You can easily use it with async pipe. Just do newsStore.news | async in your component.html, make sure you inject the store in your component.ts blog.angular-university.io/… this is a good tutorial
|
0

I did this.

getAllNews() {

    if(this.newslist != null) {
      return Observable.of(this.newslist);
    } 

    else {
      const authToken = localStorage.getItem('auth_token'); 
      const headers = new HttpHeaders() 
      .set('Content-Type', 'application/json') 
      .set('Authorization', `Bearer ${authToken}`);

      return this.httpClient
        .get('samplei/news/', { headers: headers })
        .map((response => response))
        .do(newslist => this.newslist = newslist)
        .catch(e => {
            if (e.status === 401) {
                return Observable.throw('Unauthorized');           
            }

        });
    }
  }


  getNews(id: number) { 
    return this.getAllNews().map((data:any)=> data.data.data.find(news => news.id === id)) 
  }

1 Comment

@JayDeeEss. I did this? How is it?

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.