How do i update a single item in a list that gets its data from a query result?

Actions & Logic

So I have a list of user profile cards, and on each card it shows whether you follow this user or don’t follow them.

When I pull the data from the API, I use the backend query on the list widget and create child items, and each item (user) has a “follow_status” object in the JSON that is true or false.

So the follow tag in the interface dynamically draws from the query data based on the Boolean to display the correct status.

When you click the follow/unfollow button I send an api call to update the follow status for that user. But this won't update the follow tag unless i then refresh the original list. The problem is that it takes a little too long to refresh the list so the sequence of events is a 1 second spinner, the tag remains the same status (even though in the db it is already updated) then a couple more seconds go by and then it updates to the correct status. The spinner is built into the button and it seems i can't control when it turns on and off, and surprisingly it doesn't wait until the end of the action chain (or refreshing the original list is asynchronous so it will run even after the action chain is done).

In this video you can see the FollowToggle call ends quickly but then refreshing the Search query takes time. The spinner ends fast but the word on the button only updates after the refresh is done.

https://www.loom.com/share/16022af821cc4183bacecf6e4a08f345

How do i either keep the spinner running the until the entire action chain is done, or update the data just on that single item in the list immediately after the update call before refreshing the list?

I am assuming i can't edit the query result right? Are there other solutions here i haven't thought of?

Thanks in advance.

Edit:

I have now also tried using pagination, which makes the list shorter and refreshing the list much faster. Except after all this work now for some reason refreshing the list completely resets and reloads the page and navigates back to the top, which defeats the purpose of just updating the visual button where you were so you can keep scrolling and find another user to follow or unfollow. see this video for what happens now.

Edit 2:

Support suggested the following approach (using reusable components in list):


Create a Reusable Component

- Extract the widget you’re using as the child for dynamic ListView generation into a reusable component. This helps encapsulate the functionality and makes it easier to manage individual list items without affecting the entire list.

Assign Unique Keys

- To improve Flutter’s ability to efficiently rebuild components, assign unique keys to each instance of your reusable component. The key can be based on an id from each item in the list or, if unavailable, you may generate one randomly.

Component State Management

- Within the reusable component, include a state variable such as isFollowed or isTapped to manage its internal behavior. This allows you to control state changes (like a button switching between “Follow” and “Unfollow”) locally and independently.

Button Switching Logic

- Update the button state based on the isFollowed variable. Ensure that the logic toggles the state between “Follow” and “Unfollow” when the button is pressed, making it intuitive for the user.

Action Flow for the Button

- Follow this action sequence for the button:
- Trigger API Call: When the button is pressed, make an API call to update the follow/unfollow status in your backend.
- Update State Upon Success: If the API call is successful, update the isFollowed state variable in the reusable component to reflect the change visually. This prevents the need for a full-page reload.



So i have implemented this and it does solve the speed of update of the button but it isn't persistent. Maybe my setup is still incorrect but if i scroll away after clicking a button and scroll back up it reverts to it's old mode:

https://www.loom.com/share/095eae7c742948b5b99cdb2de2bbf9d3

I'm setting the status on initialization:

I have tried adding a conditional so it on sets it once on the first init but it still doesn't work so maybe that isn't the issue. I am unclear what is happening then.

What have you tried so far?

I've tried using a local variable like "loading" but because it is associated with the page it affects all instances of the tag/button and doesn't work for just that tag. Same with animation.

I've tried creating a duplicate button to show during this process and swap them at the end of the action chain but it runs into the same problem.

Did you check FlutterFlow's Documentation for this topic?
Yes
3
2 replies