Reputation: 255
I'm building an app that fetches data from the The Movie Database API and presents a List of movies by genre.
In my view model I have a function that calls the api and makes the data available via an observable object.
import Foundation
class MovieListViewModel: ObservableObject {
@Published var movies = [Movie]()
private var fetchedMovies = [MovieList]()
var page = 1
func fetchMovies(genre: Int) {
WebService().getMoviesByGenre(genre: genre, page: page) { movie in
if let movie = movie {
self.fetchedMovies.append(movie)
for movie in movie.movies {
self.movies.append(movie)
}
}
}
page += 1
print(page)
}
}
Inside the view, I'm using onAppear to call the function and pass the genre id (Int) received from the previous view. This all works as expected.
import SwiftUI
struct MovielistView: View {
@ObservedObject private var movielistVM = MovieListViewModel()
var genre: GenreElement
var body: some View {
List {
...
}
}.onAppear {
self.movielistVM.fetchMovies(genre: self.genre.id)
}
.navigationBarTitle(genre.name)
}
}
The problem is because I'm using onAppear, the api is being hit/the view refreshed every time the user navigates back to the view.
Ideally, I'd like to call the api once during the initialising of the view model but because the genre property hasn't been initialised yet, it can't pass the parameter to the view model.
I'v tried this (below) but get the error 'self' used before all stored properties are initialized
import SwiftUI
struct MovielistView: View {
@ObservedObject private var movielistVM = MovieListViewModel()
var genre: GenreElement
init() {
movielistVM.fetchMovies(genre: genre.id) // Error here
}
var body: some View {
List {
...
}
.navigationBarTitle(genre.name)
}
}
Any help would be appreciated.
Upvotes: 0
Views: 400
Reputation: 16361
Add a genre
parameter for the init
and initialize the genre
property of MovielistView
before using it:
struct MovielistView: View {
var genre: GenreElement
//...
init(genre: GenreElement) {
self.genre = genre
movielistVM.fetchMovies(genre: genre.id)
}
//...
}
Upvotes: 1