Moya: How do i get whole response and map it into object / array using RxProvider ?

Created on 19 Jan 2017  路  7Comments  路  Source: Moya/Moya

Hi i am using newest Moya n Xcode version

I have question, i try to mapping my response into an object or an array i try both either using mapObject or mapArray but anyway always return nil or not get anything.
But If i only take from some keypath like celebrations in this http://calapi.inadiutorium.cz/api/v0/en/calendars/default/today response, it return some object response which is object only inside celebrations. How actually i need to do for getting whole response without any keyPath and map it into array or object ?

//this is my struct

struct Dates: Mappable {

    let date: String
    let season: String
    let season_week: String
    let weekday : String
    let celebrations : CalendarBible

    init(map: Mapper) throws {
        try date = map.from("date")
        try season = map.from("season")
        try season_week = map.from("season_week")
        try celebrations = map.from("celebrations")
        try weekday = map.from("weekday")
    }

}
//this one from celebrations, and it successfull if using celebrations keyPath but only return item inside celebrations.

struct CalendarBible: Mappable {

    let colour: String
    let rank: String

    init(map: Mapper) throws {
        try colour = map.from("colour")
        try rank = map.from("rank")
    }

}
public func setupRx() {
        provider = RxMoyaProvider<GitHub>()
        provider.request(.bible).mapObjectOptional(type: Dates.self).subscribe { event in
            switch event {
            case let .next(response):
                //image = UIImage(data: response.data)
                do{
                    try print("Response Map Object is : ", response)
                }catch {
                    print("Something wrong");
                }
            case let .error(error):
                print("Error Map Object : ",error)
            default:
                break
            }
        }
}

//this is json response from http://calapi.inadiutorium.cz/api/v0/en/calendars/default/today

{

    "date": "2017-01-19",
    "season": "ordinary",
    "season_week": 2,
    "celebrations": [
        {
            "title": "",
            "colour": "green",
            "rank": "ferial",
            "rank_num": 3.13
        }
    ],
    "weekday": "thursday"

}

Thank you

question rxmoya

Most helpful comment

Hey @abadikaka, what might be an error is that celebrations is in fact an array of objects, not a single object. Try to change the type of celebrations to [CalendarBible] and see if it helps.

@BasThomas I think all of the community extensions that support RxSwift has an extension on "request" (which in fact is an Observable of response) that should do the mapping auto-magically, thus I believe the syntax is correct.

Edit: Also it seems like season_week is an Int rather than String.

All 7 comments

Good question! Take a look at this community extension, which helps you map your responses to objects using ObjectMapper.

What seems to go wrong now, is that you're mapping the request immediately, instead of the response.

provider.request(.bible).mapObjectOptional(type: Dates.self).subscribe { event in
  switch event {
    case let .next(response):
      // do something with the response
    case let .error(error):
      // do something with the error
  }
}

Instead, you'd probably want something like:

provider.request(.bible).subscribe { event in
  switch event {
    case let .next(response):
      let dates = response.mapObjectOptional(type: Dates.self)
    case let .error(error):
      // do something with the error
  }
}

Hey @abadikaka, what might be an error is that celebrations is in fact an array of objects, not a single object. Try to change the type of celebrations to [CalendarBible] and see if it helps.

@BasThomas I think all of the community extensions that support RxSwift has an extension on "request" (which in fact is an Observable of response) that should do the mapping auto-magically, thus I believe the syntax is correct.

Edit: Also it seems like season_week is an Int rather than String.

@BasThomas Hi thanks for the reply, i was trying the extension but somehow it couldnt installed with my pod, seems conflicted with other pod libraries... Thank you for the solution, will try it to learn it too.

@sunshinejr Great, thank you so much Lukasz, your solution made my day.. Anyway i was the one who email you and read ur blog.. But i curious, cant we just made all of variable become String ? or need to be match with the type of web service's variable given to us ?

@abadikaka sorry if I didn't get to you, was quite a busy time for me lately. Glad I could help tho! Matching the type from the API response is a good practice, because some languages/mappers do not do the automatic casting from String to Int etc, then you might end up with error on parsing where you would be sure that it _should_ work.

@sunshinejr Okay. Thank you so much bro. Btw between mapObject and mapArray which is better ? or actually both do the same thing ?

Your current response is an object, thus you use mapObject. If you had an array of objects, like:

[{
  "date":"2017-01-19",
  "season":"ordinary",
  "season_week":2,
  "celebrations":[
    {
      "title":"",
      "colour":"green",
      "rank":"ferial",
      "rank_num":3.13
    }
  ],
  "weekday":"thursday"
}]

(notice the[ and ] surrounding {}) then you would need to use mapArray, to map more than one object.

@sunshinejr okay got it. Thank you Lukasz !

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mwawrusch picture mwawrusch  路  3Comments

hjzCy picture hjzCy  路  3Comments

PlutusCat picture PlutusCat  路  3Comments

fenixsolorzano picture fenixsolorzano  路  3Comments

JoeFerrucci picture JoeFerrucci  路  3Comments