Jake Smith
Jake Smith

Reputation: 630

Map array of objects into another array with Combine not working?

I am subscribing to a @Published array in my view model so I can .map every object appended as an array of PostAnnotations...

I am not able to map the post array into an array of PostAnnotations and get the error:

ERROR MESSAGE: Declared closure result '()' is incompatible

What am I doing wrong??

class UserViewModel: ObservableObject {
    var subscriptions = Set<AnyCancellable>()
    let newPostAnnotationPublisher = PassthroughSubject<[PostAnnotation], Never>()

    @Published var currentUsersPosts: [Posts] = []
  
    func addCurrentUsersPostsSubscriber() {
        $currentUsersPosts
             // convert each post into a PostAnnotation
            .map { posts -> [PostAnnotation] in
                 // ^ERROR MESSAGE: Declared closure result '()' is incompatible 
                //with contextual type '[SpotAnnotation]'
                posts.forEach { post in
                    let postAnnotation = PostAnnotation(post: post)
                    return postAnnotation
                }
            }
            .sink { [weak self] postAnnotations in
                guard let self = self else { return }
                // send the array of posts to all subscribers to process
                self.newPostAnnotationsPublisher.send(postAnnotations)
            }
            .store(in: &subscriptions)
    }

     func loadCurrentUsersPosts() {
         PostApi.loadCurrentUsersPosts { response in
             switch response {
             case .success(let posts):
                 self.currentUsersPosts.append(contentsOf: spots)
             case .failure(let error):
                 //////
             }
         }
     }

}

Upvotes: 1

Views: 2635

Answers (1)

jnpdx
jnpdx

Reputation: 52347

forEach doesn't return a value. You want map, which returns a new collection based on the transform performed inside the closure:

.map { posts -> [PostAnnotation] in
    posts.map { post in
        let postAnnotation = PostAnnotation(post: post)
        return postAnnotation
    }
}

Or, even shorter:

.map { posts -> [PostAnnotation] in
    posts.map(PostAnnotation.init)
}

And, even shorter (although, I'd argue that it starts losing readability at this point):

.map { $0.map(PostAnnotation.init) }

Upvotes: 5

Related Questions