How to load value of data using links on JSON payload


#1

Hi all,

I’m doing a little project to load some images from Nasa’s image API.

I’ve created an image model with ember data and managed to load the following data using external API from nasa - https://images-api.nasa.gov/search ?q=apollo

The last property that I would like to include in my image model is a string (link of json object e.g. https://images-assets.nasa.gov/image/as11-40-5874/collection.json), and going to this link, you get an array of strings (image urls).

What I want is to have an array of these image urls as the value of href instead of the json link that points to these arrays. How do I go about getting ember data to load these arrays from the said link in this model? Do I need to create another model (as image-urls)? They are just arrays with no ids, so I’m not sure if this is appropriate.


My image model:

"nasa_id": "as11-40-5874", 
"center": "JSC", 
"date_created": "1969-07-21T00:00:00Z", 
"description": “some string”, 
"keywords": [ "APOLLO 11 FLIGHT", "MOON", "LUNAR SURFACE", "LUNAR BASES", "LUNAR MODULE", "ASTRONAUTS", "EXTRAVEHICULAR ACIVITY" ], "media_type": "image", 
"title": “some string“
“href”: "https://images-assets.nasa.gov/image/as11-40-5874/collection.json"


My adapter (adapters/image):

import DS from 'ember-data';

export default DS.JSONAPIAdapter.extend({
    host: 'https://images-api.nasa.gov',
    namespace: 'search?',

    urlForQuery (query, modelName) {
      return `${this.host}/${this.namespace}`;
    }
});


My serializer (serializers/image):

import DS from 'ember-data';
import { underscore } from '@ember/string';

export default DS.JSONAPISerializer.extend({

    keyForAttribute(attr, method) {
        return underscore(attr);
    },
   
    normalizeResponse (store, primaryModelClass, payload, id, requestType) {

        payload.data = payload.collection.items.map((image) => {
            let dataAttributes = image.data[0];

            return {
              id: image.data[0].nasa_id,
              type: 'image',
              attributes: dataAttributes,
            }
        });


        return this._super(store, primaryModelClass, payload, id, requestType);
    }
});

If anyone can shed some light that would be most appreciated.

Cheers


#2

I see two choices.

The first option is to extend your Adapter so that it does the second API request and inlines the answer. This would involve implementing findRecord, findAll, and query so that each one calls super, and then you take the result, find the href property, do your own ajax request to turn it into a list of image urls, and modify the response before returning it from your method.

The second option is to model this as a real relationship and leave the loading up to ember-data. This would indeed involve creating a second model to represent the image urls. You can use the actual URLs as the IDs, which would ensure uniqueness.


#3

I should clarify the second option, because it has two variations.

One variant is to model every URL as a separate record of type image-urls, and there would be a hasMany relationship to them.

The second variant is to make the second model type be something like image-url-lists, and then the relationship is a belongsTo. This may be simpler to wire up, because the ID of the image-url-lists can be the collection.json URL, and then it’s easy to write an adapter that loads that and results in a model with a urls attribute that is just a list of strings.


#4

Perfect thanks for that! I had a hunch that I would need to create Ajax call if I’m not creating a separate model but this clarifies things up for me and I think it’s easier to do the latter.

Cheers!