0

I have a scenario whereby I have a list of items which all have NavigationLinks embedded. However, the destination of that link should vary depending on the item selected. The added complication though is that the value which I need to check will only be known once the item has been selected. So, here is the stack with the NavigationLinks:

LazyVStack(alignment: .center) {
                Section(header: storeStatusOpenHeader()) {
                    ForEach(viewModel.shownOpenStores, id: \.self) { details in
                        
                        StoreCardInfoView(storeDetails: details)
                        
                        NavigationLink(destination:
                                        FulfilmentTimeSlotSelectionView(viewModel: .init(container: viewModel.container))
                                        .onAppear {
                            viewModel.selectStore(id: details.id)
                        }) {
                            StoreCardInfoView(storeDetails: details)
                        }
                    }
                }
            }

Currently we redirect directly to FulfilmentTimeSlotSelectionView. However, in the viewModel when selectStore() is called, we a key property that we need to check before knowing where to redirect the user. Firstly, we call an endpoint which returns a bunch of available delivery days for the store selected. Using Combine, we listen for the response here with the following subscription (the selectedOrderMethod is incidental with regards to this question so can be ignored):

private func setupSelectedRetailsStoreDetails() {
        $selectedRetailStoreDetails
            .sink { [weak self] details in
                guard let self = self else { return }

                switch self.selectedOrderMethod {
                case .delivery:
                    if let deliveryDays = details.value?.deliveryDays {
                        self.futureFulfilmentAvailable = !(deliveryDays.count == 1 && deliveryDays[0].date == "2022-02-24") // hard coded for now i.e. today
                    }
                case .collection:
                    if let collectionDays = details.value?.collectionDays {
                        self.futureFulfilmentAvailable = !(collectionDays.count == 1 && collectionDays[0].date == "2022-02-24") // hard coded for now i.e. today
                    }
                default:
                    print("***") // TBC
                }
            }
            .store(in: &cancellables)
    }

So here on the viewModel, we set a key Boolean futureFulfilmentAvailable. If this value is true, I want to redirect the user to one view (where they would select a timeslot), but if it is false, I would want to direct them to a different view.

Obviously the issue with the NavigationLink here is that when it is tapped, the call has not yet been made and so the Bool has not been set, meaning we don't know where to redirect the user.

Is there a clean way around this that I am not seeing yet?

DevB1
  • 1,235
  • 3
  • 17
  • 43
  • I have proposed [here](https://stackoverflow.com/questions/71227307/reverse-animation-for-navigationlink/71227940#71227940) a simple way to mimic `NavigationLink`. The navigation occurs with `.onTapGesture()`, so you can evaluate your input before navigating. I hope this works. – HunterLion Feb 24 '22 at 15:32
  • see also these SO posts: https://stackoverflow.com/questions/69228365/swift-ontapgesture-with-navigationlink and https://stackoverflow.com/questions/67240115/can-a-navigationlink-perform-an-async-function-when-navigating-to-another-view – workingdog support Ukraine Feb 24 '22 at 22:52

0 Answers0