Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incremental adding element to a SectionModel cause duplicate item issue #251

Open
ZZHHAANNGG opened this issue Aug 12, 2018 · 8 comments
Open

Comments

@ZZHHAANNGG
Copy link

ZZHHAANNGG commented Aug 12, 2018

I have a one section array. Whenever the user scrolls up the tableview, it loads the additional prefetched data from an API and adds the identical data to the end of the AnimatableSectionModelType Item. The section header is always an empty string. It crashes because there is a duplicate item at Indexpath(0,0).

Item CustomerJSON(UserId: Optional("016f0166-ead2-4719-88be-3f3bc45677c1"), UserName: Optional("13923715796"), CreateTime: Optional("2017/6/8 23:38:53"), GoodsCount: Optional(0), GoodsPrice: Optional(0.0)) has already been indexed at (0, 0)

What do I miss?

struct SectionOfCustomerJSON {
    var header: String
    var items: [Item]
}

extension SectionOfCustomerJSON: AnimatableSectionModelType {
    typealias Item = CustomerJSON
    
    var identity:String{
        return header
    }
    
    init(original: SectionOfCustomerJSON, items: [Item]) {
        self = original
        self.items = items
    }
}

let customerList = BehaviorRelay(value: Array<SectionOfCustomerJSON>())


/// add new elements logic
// previous array elements
let existedArray = self.customerList.value.last?.items ?? []

// new elements from the API
let newCustomerList:[CustomerJSON] = existedArray + customerList

// merge the array and create a new SectionModel instance
self.customerList.accept( [SectionOfCustomerJSON(header: "", items: newCustomerList)] )

The data looks this

OLD ARRAY:

[app.SectionOfCustomerJSON(header: "",
 items: [app.CustomerJSON(UserId: "016f0166-ead2-4719-88be-3f3bc45677c1,
 UserName: "13923715796,
 CreateTime: "2017/6/8 23:38:53,
 GoodsCount: 0),
 GoodsPrice: 0.0)),
 GoodsPrice: 13.0)),
 app.CustomerJSON(UserId: "7eba35d2-8f5c-405a-9e60-faf7559071c7,
 UserName: "13126887332,
 CreateTime: "2018/1/25 10:31:14,
 GoodsCount: 1),
 GoodsPrice: 18.0))])]


NEW ARRAY:

 [app.SectionOfCustomerJSON(header: "",
 items: [app.CustomerJSON(UserId: "016f0166-ead2-4719-88be-3f3bc45677c1,
 UserName: "13923715796,
 CreateTime: "2017/6/8 23:38:53,
 GoodsCount: 0),
 GoodsPrice: 0.0)),
 app.CustomerJSON(UserId: "7eba35d2-8f5c-405a-9e60-faf7559071c7,
 UserName: "13126887332,
 CreateTime: "2018/1/25 10:31:14,
 GoodsCount: 1),
 GoodsPrice: 18.0)),
 app.CustomerJSON(UserId: "00e0908c-0b08-403b-b72a-a199955054c8,
 UserName: "18112709797,
 CreateTime: "2017/8/19 14:01:06,
 GoodsCount: 26),
 GoodsPrice: 340.0))])]
@mkko
Copy link

mkko commented Aug 16, 2018

What is a CustomerJSON? Is there a possibility that its identity is not unique?

@newPrimitives
Copy link

I have the same problem, almost identical code @ZZHHAANNGG did you manage to figure it out?

@460565420
Copy link

i have the same question, where can i set a different id ?

@buithuyen
Copy link

I have the same one.

@dfmarulanda
Copy link

Same

@mkko
Copy link

mkko commented Apr 29, 2019

@ZZHHAANNGG, Can you paste the implementation details for CustomerJSON here? How does its implementation of IdentifiableType look like?

Anyone who's having issues, there's definitely a reason why the Differentiator thinks the item has been added and it is most likely to do with the item's identity. It has to be unique for each item.

@dfmarulanda
Copy link

import RxCocoa
import RxSwift
import RxKingfisher
import Differentiator

struct ItemExploreCellViewModel {
  let username: Driver<String>
  let userPic: Observable<URL?>
  let title: Driver<String>
  let description: Driver<String>
  let wishedCount: Driver<String>
  let imageURL: Driver<[String?]>
  let isWanted: Driver<Bool>
  let itemId: Int
  let isOwner: Driver<Bool>
  
  let item: ItemInfo
  init (item: ItemInfo, userId: Int) {
    self.item = item
    self.itemId = item.id
    self.username = Driver.just(item.swapperByOwnerId?.username ?? "")
    self.userPic = Observable.just(item.swapperByOwnerId?.profilePicture ?? "https://images.crowdswap.com/octavio.png").map { URL(string: $0) }
    self.title = Driver.just(item.name ?? "")
    self.description = Driver.just(item.description ?? "")
    self.wishedCount = Driver.just(item.countWants ?? "")
    self.imageURL = Driver.just(item.pictures ?? ["https://i0.wp.com/oij.org/wp-content/uploads/2016/05/placeholder.png"])
    self.isWanted = Driver.just(item.isWanted ?? false)
    self.isOwner = Driver.just(item.swapperByOwnerId?.id == userId)
  }
}

extension ItemExploreCellViewModel: IdentifiableType {
  typealias Identity = Int
  var identity: Int {
    return item.id
  }
}

extension ItemExploreCellViewModel: Equatable {
  static func == (lhs: ItemExploreCellViewModel, rhs: ItemExploreCellViewModel) -> Bool {
    return lhs.item.id == rhs.item.id  &&
      lhs.item.name == rhs.item.name &&
      lhs.item.description == rhs.item.description &&
      lhs.item.countWants == rhs.item.countWants &&
      lhs.item.pictures == rhs.item.pictures
  }
}

@dfmarulanda
Copy link

Did you find a workaround?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants