2

I'm new in Angular, I am making an app in Angular 5 to show images with information relative to the image, the app has a thumbnails page an when you click you can see the image with a description or a video, I'm fetching all the data from a service and an array inside the service but I need to change and instead of fetch the data from the array I need to do it from a JSON but keeping all the functionality I already have, but when I fetch the data from the JSOM I just cant see the information of image when I click.

This is the service with the array I need to change for JSON:

export class ArticulosService {
enter code here @Injectable()
export class ArticulosService {

constructor(private http: HttpClient) {}

visibleImages = [];
private url: string = '../assets/data/articulos.json';

getImages() {
  return this.visibleImages = IMAGES.slice(0);
}

getImage(id: number) {
  return IMAGES.slice(0).find(image => image.id === id);
}

}
const IMAGES = [
{..this is the array..} ];

This is the component with the image thumbnails here you can see all the thumbnails from the IMAGES array

export class HomeComponent implements OnChanges {
images: any[];
visibleImages: any[] = [];

constructor(private articulosService: ArticulosService) {
 this.visibleImages = this.articulosService.getImages();
}

ngOnChanges() {
 this.visibleImages = this.articulosService.getImages();
}

}

This is the image page component where you see the image title etc..

export class TutorialPostsComponent implements OnInit {
image:any

visibleImages: any[] = [];
constructor(private articulosService: ArticulosService, private route: 
ActivatedRoute) {
  this.visibleImages = this.articulosService.getImages();
}

ngOnInit() {
  this.image = this.articulosService.getImage(
  +this.route.snapshot.params['id']
);
}
}

Here I changed the service to fetch from a JSON instead of the hardcoded array

   export class ArticulosService {
   private _url: string = '../assets/data/articulos.json';

  constructor(private _http: HttpClient) {}

  getImages(): Observable<TutoGaleria[]> {
    return this._http.get<TutoGaleria[]>(this._url)
  }
  }

I can see the data in the thumbnails but this data is not passing for the image details as when I was using the array.

I think is related to the getImage(id: number) function I don't know how to do this part fetching from a JSON.

How can I do the same functionality with the JSON?

2 Answers 2

1

The problem is, that you were returning an array, but you now return an Observable.

That is a different type of data, and a whole programming paradigm: you are now not passing objects, but you are passign "events", that need to be handled.

the this.visibleImages = this.articulosService.getImages(); line is now working differently then you expect it, because you won't get the object you requre, but the Observable reference, which will give you the results in the future.

To understand this, I really recommend you read the linked tutorial. Your solutions will be something like this:

const getImagesSubscription = this.articulosService.getImages().subscribe(
  (response) =>  {this.visibleImages = response;},
  (error) => { << handle errors here >> },
  () => { << complete event here >> });
Sign up to request clarification or add additional context in comments.

Comments

1

Fetching data from a json file is asynchronous, so it's a bit different from getting your data from an array and you need to consider that.

Your service will look like something like that :

export class ArticulosService {
   private _url: string = '../assets/data/articulos.json';

   constructor(private _http: HttpClient) {}

   getImages(): Observable<TutoGaleria[]> {
      return this._http.get<TutoGaleria[]>(this._url)
   }

   getImage(id: string): Observable<TutoGaleria> {
      return this.getImages()
         .map(images => images.filter(image => image.id === id))
         .filter(images => images.length)
         .map(images => images[0])
   }
}

And your component :

export class TutorialPostsComponent implements OnInit {
    image:any
    visibleImages: any[] = [];

    constructor(private articulosService: ArticulosService, 
                private route: ActivatedRoute) {
        this.visibleImages = this.articulosService.getImages();
    }

    ngOnInit(){
         this.articulosService.getImage(this.route.snapshot.params['id'])
              .subscribe(image => this.image = image);     
    }

}

Hope that helps

2 Comments

Hello I tested this solution and doesn't work and give this errors: - Operator '===' cannot be applied to types 'number' and 'string'. - Argument of type '(images: TutoGaleria[]) => number' is not assignable to parameter of type '(value: TutoGaleria[], index: numb er) => boolean'.
I supposed your id was a string but it looks like it's a number. Don't take it to the word, adapt it to your data structure :)

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.