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

add toDictionary, toJSONString #2

Open
wants to merge 5 commits into
base: master
Choose a base branch
from

Conversation

iamchiwon
Copy link

My project using Firebase, needs convertings between Model and Dictionary, [String:Any].
So I added "toDictionary()"
and "toJSONString()" for POST request

  1. when error occured, toDictionay() and toJSONString() returns empty not nil , followed your map() that returns empty Data when error
  2. respected your coding convention, 2 space indent, and space after colon

@codecov-io
Copy link

codecov-io commented Jan 2, 2018

Codecov Report

Merging #2 into master will decrease coverage by 4.87%.
The diff coverage is 83.56%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master       #2      +/-   ##
==========================================
- Coverage    92.5%   87.62%   -4.88%     
==========================================
  Files           4        3       -1     
  Lines          40       97      +57     
  Branches        3        0       -3     
==========================================
+ Hits           37       85      +48     
- Misses          0       12      +12     
+ Partials        3        0       -3
Impacted Files Coverage Δ
Sources/RxCodable/ObservableType+RxCodable.swift 87.09% <82.6%> (-3.82%) ⬇️
Sources/RxCodable/Single+RxCodable.swift 87.87% <84%> (-3.04%) ⬇️
Sources/RxCodable/Maybe+RxCodable.swift 87.87% <84%> (-3.04%) ⬇️
Sources/TestUtil/Fixture.swift

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 3e4c053...ef78616. Read the comment docs.

}

public extension ObservableType where E: Encodable {
public func toDictionary() -> Observable<[String:Any]> {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. How about renaming it to mapDictionary()?
  2. I think we need a parameter of JSONEncoder. map() takes an instance of JSONDecoder as a parameter.
  3. Could you please append a whitespace after a colon?
    - [String:Any]
    + [String: Any]
  4. How do you think of supporting mapping json array?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. like toBlocking(), toArray(). toXXX() feels extract some data. toDictionary() is more clear for me, aren't you? ( I understand your side, changing data should start with map... )
  2. Yes. It seems necessary
  3. my mistake.
  4. why not

Copy link
Owner

@devxoul devxoul Jan 3, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. It's not about extracting data. It's obviously mapping data. I think it would be better to rename it to mapDictionary().
  2. Could you write that one?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. then toJSONString() needs rename to mapJSONString(), too?

return self.map { encodable -> [String: Any] in
let data = try JSONEncoder().encode(encodable)
let dictionary = try JSONSerialization.jsonObject(with: data) as? [String: Any]
return dictionary ?? [:]
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This default value can cause an unexpected result. I think we should treat a casting failure as an error.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good point!
access empty dictionary makes crash.. it would be better throw error

unit test testMapCodableArrayToJSONString() added : [Encodable] -> toJSONString()
@iamchiwon
Copy link
Author

  1. toDictionary(), toJSONString() got parameter JSONEncoder as first with no name.
  2. toDoctionary() throws RxError.noElements.
    RxError.noElements seems not exactly matched, but I don't want to create new ErrorType
  3. UnitTest added, that shows [Encodable] ==> JSON string.

return self.map { encodable -> [String: Any] in
let data = try (encoder ?? JSONEncoder()).encode(encodable)
let dict = try JSONSerialization.jsonObject(with: data) as? [String: Any]
guard let dictionary = dict else { throw RxError.noElements }
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RxError.noElements should not be used here. It would be better to create a new error type for RxCodable.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm.. It should be

Copy link
Author

@iamchiwon iamchiwon Jan 3, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how about this?

enum RxCodableError : Error, CustomDebugStringConvertible {
    case decodeFail
    case encodeFail

    var debugDescription: String {
        switch self {
        case .decodeFail:
            return "Encoding failure"
        case .encodeFail:
            return "Decoding failure"
        } 
    }
}

Copy link
Owner

@devxoul devxoul Jan 3, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should give more detailed information. And CustomDebugStringConvertible is not necessary.

enum RxCodableError: Error {
  case castingFailure(Any, Any.Type)
}

You can refer to RxJSONError.

return self.map { encodable -> String in
let data = try (encoder ?? JSONEncoder()).encode(encodable)
let json = String(data: data, encoding: encoding)
return json ?? "{}"
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please don't use default value here.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

got it

RxCodableError added. thows mapDictionary, mapJSONString
feature added that mapping [Dictionary] ==> [Encodable]
}

public extension ObservableType where E == [[String: Any]] {
public func map<T>(_ type: Array<T>.Type, using decoder: JSONDecoder? = nil) -> Observable<[T]> where T: Decodable {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this? The 'array mapping' I meant was about func mapArray() which maps Observable<[T]> to Observable<[[String: Any]]>.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh.. my misunderstood. now I see.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm.. It's not as easy as I thought.

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

Successfully merging this pull request may close these issues.

4 participants