Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to chain multiple API calls using dataTaskPublisher?

I want to get data from REST API and in order to do that, I need to first get an array of IDs - 1st call. After that, I need to do an API call using each ID. I don't want to use completionHandlers but Combine. I started with dataTaskPublishers but I am not sure how can I chain them to work properly 🤔

Here is my code so far:

   private func getIDs(for type: DataType) -> AnyPublisher<[ID], Error> {
        guard let url = URL(string: "url")
            else { fatalError("Wrong URL") }

        return session.dataTaskPublisher(for: url)
            .receive(on: RunLoop.main)
            .map { $0.data }
            .decode(type: [ID].self, decoder: decoder)
            .eraseToAnyPublisher()
    }

    private func getData(with id: ID) -> AnyPublisher<MyData, Error> {
        guard let url = URL(string: "url_with_id")
            else { fatalError("Wrong URL") }
        return session.dataTaskPublisher(for: url)
            .receive(on: RunLoop.main)
            .map { $0.data }
            .decode(type: MyData.self, decoder: decoder)
            .eraseToAnyPublisher()
    }

I am not really sure how can I connect them to get something that is assignable to my state variable - array of MyData.

like image 388
czater Avatar asked Aug 12 '19 02:08

czater


People also ask

Which function will you use to call multiple APIs in Reactjs?

Call The APIs with Axios and Promise. const axios = require('axios'); Notice the last function added to the following file, we are passing all three calls to the Promise. all function as an array and mapping them to merge all the values and produce the result at the end.


1 Answers

As suggested in https://stackoverflow.com/a/56786412/1271826, you can use collect():

func getAllData(for type: DataType) -> AnyPublisher<[MyData], Error> {
    getIDs(for: type).flatMap { ids in
        Publishers.Sequence(sequence: ids.map { self.getData(with: $0) })
            .flatMap { $0 }
            .collect()
    }.eraseToAnyPublisher()
}
like image 142
Rob Avatar answered Nov 15 '22 05:11

Rob