6. Connect your queries to your UI
In this chapter you are going to display a list of Launches in a List.
Configure LaunchListViewModel
In LaunchListViewModel
add a new variable to hold the launches returned by the query:
1@Published var launches = [LaunchListQuery.Data.Launches.Launch]()
2@Published var appAlert: AppAlert?
3@Published var notificationMessage: String?
Next, replace the TODO
in the loadMoreLaunches()
method with the code to run the LaunchListQuery
:
1Network.shared.apollo.fetch(query: LaunchListQuery()) { [weak self] result in
2 guard let self = self else {
3 return
4 }
5
6 switch result {
7 case .success(let graphQLResult):
8 if let launchConnection = graphQLResult.data?.launches {
9 self.launches.append(contentsOf: launchConnection.launches.compactMap({ $0 }))
10 }
11
12 if let errors = graphQLResult.errors {
13 self.appAlert = .errors(errors: errors)
14 }
15 case .failure(let error):
16 self.appAlert = .errors(errors: [error])
17 }
18}
GraphQLResult
has both a data
property and an errors
property. This is because GraphQL allows partial data to be returned if it's non-null.
In the example we're working with now, we could theoretically obtain a list of launches, and then an error stating that a launch with a particular ID could not be retrieved.
This is why when you get a GraphQLResult
, you generally want to check both the data
property (to display any results you got from the server) and the errors
property (to try to handle any errors you received from the server).
As you can see in the code, the sample project has already provided an easy way to display error alerts by simply assigning the desired value to the appAlert
property.
Use Launches in the UI
First let's update our LaunchRow
view to be able to display the data for a specific Launch
. At the top of the file add import RocketReserverAPI
and then add the following variable:
1let launch: LaunchListQuery.Data.Launches.Launch
2private let placeholderImg = Image("placeholder")
Then let's update one of our Text views to show the launch site:
1VStack(alignment: .leading) {
2 Text("Mission Name")
3 Text(launch.site ?? "Launch Site")
4 .font(.system(size: 14))
5}
Now that our LaunchRow
is updated, let's move over to LaunchListView
and start displaying our Launches in the list.
Update the ForEach
loop to loop through every launch item from our viewModel
and create a LaunchRow
for it:
1ForEach(0..<viewModel.launches.count, id: \.self) { index in
2 LaunchRow(launch: viewModel.launches[index])
3}
The last step is to call the loadMoreLaunches
method we updated earlier to actually query the server for data. To do this update the TODO
in the .task { }
in LaunchListView
to the following:
1.task {
2 viewModel.loadMoreLaunches()
3}
Test your query
Build and run the application, you now have a UI connected to your GraphQL queries 🚀.
Next, you'll add more info to the list to make it look nicer!