GithubHelp home page GithubHelp logo

Comments (11)

dmcrodrigues avatar dmcrodrigues commented on April 28, 2024 2

For this kind of use cases I think a Action+CocoaAction approach its the best option because it handles both validation and execution of the task.

let textFieldUsernameSignal = textFieldUserName.reactive.continuousTextValues
let textFieldPasswordSignal = textFieldPassword.reactive.continuousTextValues

let validator = Signal.combineLatest(textFieldUsernameSignal, textFieldPasswordSignal)
    .map { username, password in
        return username?.characters.count ?? 0 > 0 && password?.characters.count ?? 0 > 0
}

let enabledIf = Property(initial: false, then: validator)

let action = Action<(String?, String?), Void, NoError>(enabledIf: enabledIf) { username, password in
    // Return a signal producer to perform the side effect...
}

navigationItem.rightBarButtonItem.reactive.pressed = CocoaAction(action, input: (textFieldUserName.text, textFieldPassword.text))

from reactiveswift.

andersio avatar andersio commented on April 28, 2024 2
CocoaAction(action) { _ in (textFieldUserName.text, textFieldPassword.text) }

would do.

from reactiveswift.

artshin avatar artshin commented on April 28, 2024 1

Alright, I gave it a couple more shots and this is what I came up with:

// bind view model to UI first
textFieldUserName.reactive.text <~ viewModel.username
textFieldPassword.reactive.text <~ viewModel.password

// bind UI to view model
viewModel.username <~ textFieldUserName.reactive.continuousTextValues
    .map { $0!.trimmingCharacters(in: .whitespacesAndNewlines) }
viewModel.password <~ textFieldPassword.reactive.continuousTextValues
    .map { $0!.trimmingCharacters(in: .whitespacesAndNewlines) }

navigationItem.rightBarButtonItem?.isEnabled = false
navigationItem.rightBarButtonItem!.reactive.isEnabled <~ Property.combineLatest(viewModel.username, viewModel.password)
    .map { !$0.isEmpty && !$1.isEmpty }.signal.observe(on: UIScheduler())

The only problem appears in making a signal work with rightBarButtonItem. When ViewController shows up on screen, .map { !$0.isEmpty && !$1.isEmpty } is getting called and the result is false (which is correct), but the button remains active anyway. Entering values in textfields yields expected behaviour.

from reactiveswift.

EvilNOP avatar EvilNOP commented on April 28, 2024

@dmcrodrigues
Did you notice that:

/// Initialize a CocoaAction that invokes the given Action with the given
/// constant.
///
/// - parameters:
///   - action: The Action.
///   - input: The constant value as the input to the action.
public convenience init<Input, Output, Error>(_ action: Action<Input, Output, Error>, input: Input) {
    self.init(action, { _ in input })
}

The input of the CocoaAction is constant, so your following code:

navigationItem.rightBarButtonItem.reactive.pressed = CocoaAction(action, input: (textFieldUserName.text, textFieldPassword.text))

won't work, cuz textFieldUserName.text and textFieldPassword.text would both be empty string at first which means:

let action = Action<(String?, String?), Void, NoError>(enabledIf: enabledIf) {
    username, password in

}

username and password also empty.

from reactiveswift.

EvilNOP avatar EvilNOP commented on April 28, 2024

@andersio Cool stuff!

from reactiveswift.

EvilNOP avatar EvilNOP commented on April 28, 2024
/// Initializes an action that will be conditionally enabled, and creates a
/// SignalProducer for each input.
///
/// - parameters:
///   - enabledIf: Boolean property that shows whether the action is
///                enabled.
///   - execute: A closure that returns the signal producer returned by
///              calling `apply(Input)` on the action.
public init<P: PropertyProtocol>(enabledIf property: P, _ execute: @escaping (Input) -> SignalProducer<Output, Error>) where P.Value == Bool

Q1: A closure that returns the signal producer returned by calling apply(Input) on the action, what does it mean? Should I call the apply method? And in what kink of condition call the apply?

Q2: What kind of SignalProducer should I return?

Let's say that there's two text fields (one for username, the other for password), and a sign in button.
When the user clicked sign in button which will do some checking, then , return a Bool indicate that whether successfully sign in.

I've already typing some code:

let signUpActiveSignal = Signal.combineLatest(validUsernameSignal, validPasswordSignal).map {
    (isValidUsername, isValidPassword) in
            
     return isValidUsername && isValidPassword
}
        
let signInButtonEnabledProperty = Property(initial: false, then: signUpActiveSignal)
        
let action = Action<(String, String), Bool, NoError>(enabledIf: signInButtonEnabledProperty) {
    (username, password) in
            
    return ?
}
        
signInButton.reactive.pressed = CocoaAction<UIButton>(action) {
    _ in
            
    (self.usernameTextField.text!, self.passwordTextField.text!)
}

Could somebody help me fix the blank in Action initialization?

from reactiveswift.

andersio avatar andersio commented on April 28, 2024

Action is like a serial queue of a preassigned, fixed work, defined by the execute closure in its initializer.

You call apply to make a unit of work that is customized for the input to apply. Then you may start the unit of work (the returned producer from apply) and get notified of anything about it.

You should return a producer that does work with regard to the input. Note that the work can be asynchronous.

    // SignalProducer<Output, Error>
    return SignalProducer<Bool, NoError> { observer, disposable in
        observer.send(value: authManager.isValid(username, password))
        observer.sendCompleted()
    }

from reactiveswift.

EvilNOP avatar EvilNOP commented on April 28, 2024

So now I have this:

let action = Action<(String, String), Bool, NoError>(enabledIf: signInButtonEnabledProperty) {
    (username, password) in
            
    return SignalProducer<Bool, NoError> { observer, disposable in
        observer.send(value: authManager.isValid(username, password))
        observer.sendCompleted()
    }
}

How do I know whether the user sign in successfully?

It's that?

action.values.observeValues {
    success in

    if success {
        print("Successfully sign in.")
}

from reactiveswift.

andersio avatar andersio commented on April 28, 2024

Yeah.

from reactiveswift.

EvilNOP avatar EvilNOP commented on April 28, 2024

from reactiveswift.

idelfonsog2 avatar idelfonsog2 commented on April 28, 2024

textFieldPassword.reactive.text <~ viewModel.password
viewModel.password <~ textFieldPassword.reactive.text

what is exactly happening here? What's the type of viewModel.password?

from reactiveswift.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.