1

I'm getting started with the Amplify Framework and I'm following Building an Android app with AWS Amplify – Part 1 from the AWS blog. The code being used there appears to be outdated (2018) since there's nothing like that in the Amplify Libraries.

I'm stuck at the part where I need to display a RecyclerView of items. In that article, you can get the items like this:

response.data().listPets().items()

However, in the current docs, there's a response.getData() method which returns an Iterator<T>, that you can loop through.

What I'd like is to get a List<T> to feed a RecyclerView.Adapter.

Please advise.

Jameson
  • 6,400
  • 6
  • 32
  • 53
Zero
  • 717
  • 6
  • 21

2 Answers2

1

I was following through the latest implementations in Amplify , using the RxAmplify and a sample todo application, which internally uses rxJava. So I used the below code to query through the datastore and obtain a list of values which can be used to update the recyclerview adapter. The

toList()

part converts the query results to list which can be used in the adapter.

RxAmplify.DataStore.query(Todo.class)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .toList()
            .subscribe(todolist->{
                adapter.updateList(todolist);
                adapter.notifyDataSetChanged();
            });

The part

.subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread())

is important else you wouldn't be able to access the UI, and will throw exception.

Dharman
  • 30,962
  • 25
  • 85
  • 135
0

AppSync SDK vs. Amplify Android?

That blog from 2018 was written with the AWS Android AppSync SDK in mind. The README on the AppSync SDK includes notes on code generation from a schema file. If you will continue to follow the 2018 blog, I would supplement your exercise with that documentation.

This year, AWS' public documentation has been updated to point customers to the new Amplify Android library. The Amplify CLI (amplify) has also been updated to work with the Amplify Android library. The Amplify CLI will currently generate Java code that can be used by the Amplify Android API and DataStore categories.

TLDR, if you're just getting going, I'd work from the Tutorial section of the AWS Amplify Android docs.

There's also a more recent (May 2020) blog post about AppSync that you can follow, here.

Iterator<T> and RecyclerView.Adapater

There are a ton of ways to pass the results into the adapter, of varying complexity.

The most straight-forward approach would be something like this:

First, back your adapter with a List<SomeModel>. The List<SomeModel> can be updated after you create the ItemAdapter, by design:

final class ItemAdapter implements RecyclerView.Adapter<ItemHolder> {
    private final List<SomeModel> data;

    ItemAdapter(List<SomeModel> data) {
        this.data = data;
    }
}

Then, in the Amplify callback, update the List, and notify the adapter that the dataset has changed:

List<SomeModel> models = new ArrayList<>();
ItemAdapter adapter = new ItemAdapter(models);
Amplify.API.query(SomeModel.class,
    iterator -> {
        if (!iterator.hasNext()) return;
        models.clear();
        while (iterator.hasNext()) {
            models.add(iterator.next());
        }
        adapter.notifyDataSetChanged();
    },
    failure -> {
        // As an exercise: display an
        // error item into the RecyclerView.
    }
);
Jameson
  • 6,400
  • 6
  • 32
  • 53
  • OK. This works, but is unsatisfactory. I'm now forced to think about how it'd work in an architecture like MVVM, and my impression is that it'll require significant adjustments. You mentioned that _There are a ton of ways to pass the results into the adapter, of varying complexity_ so what other ways are there that fit in with MVVM? – Zero Jun 10 '20 at 10:59
  • @Duos Your original post said nothing about MVVM. I suggest learning how a `RecyclerView` works, before worrying about that. – Jameson Jun 10 '20 at 14:34
  • Alright. MVVM aside, the real crux of my question was how I could send a request, and get a response of `List`. Meaning all the processing is done on the server. But if I get an `Iterator`, now I'll have to do the processing on the client. Whether I perform the looping inside a `RecyclerView` or within a MVVM architecture, it's still processing on the client. I want to avoid that if I can. – Zero Jun 10 '20 at 15:25
  • Hey @Duos! You will use a `RecyclerView` in your MVVM architecture. An `Iterator` is a standard Java interface to step through an ordered collection. The processing is on the order of single machine instructions on the client, which is several orders of magnitude smaller than a single network call. Come join us on our Discord support channel. I'd love to chat more. https://discord.gg/jWVbPfC – Jameson Jun 10 '20 at 16:23