Jasonette / JASONETTE-iOS

📡 Native App over HTTP, on iOS
https://www.jasonette.com
MIT License
5.27k stars 352 forks source link

$href action not firing "success" #332

Closed darenr closed 6 years ago

darenr commented 6 years ago

demo: https://jasonbase.com/things/74L2

click the label, click back, no "success" alert.

Incidentally this doesn't even push to the new href on android. I'll file a separate bug for that.

gliechtenstein commented 6 years ago

Here's the documentation for how $href and success works http://docs.jasonette.com/actions/#success-callback

You need to use $ok action from the next view.

darenr commented 6 years ago

right, I've used that, but I would have to add a button to issue the $ok action which I can't do with a push-transition right? The action is implicit, there's no way that I can see from the docs of doing that. Shouldn't the implicit back transition issue the $ok action and fire success? My expectation was that it would which is why I created this issue.

gliechtenstein commented 6 years ago

The $ok action is like $back, except you can pass back payload as $jason, which means it can be called like any other actions at any point you like.

Shouldn't the implicit back transition issue the $ok action and fire success?

I don't understand how this would work. If you have a hypothetical scenario and a pseudocode that would make this work, feel free to share.

I guess I don't understand the comment overall. It would help if you post a short JSON snippet of what you think should have worked but didn't work.

darenr commented 6 years ago

Thanks. The link in the original issue above should show what I was expecting to work. After push transitioning to a view and then swiping/clicking back I'd like to catch that event. What would be better would be if I can intercept the view's return and call the $ok or $back with parameters but that happens without me having any control I think.

Really all I want to do is when the user returns from a linked view perform some action. Let's say you had controls on the view and their state might have been changed, a way to communicate this back to the original view when the use clicks back without tapping a button element. This is all based on whether or not I'm right in thinking that the view's back < button isn't one I can do anything with. Am I right in thinking that the $back and $ok actions are actions callable only from user defined components (buttons, items)

Hope this makes sense. This is low priority though so don't waste any cycles on it.

gliechtenstein commented 6 years ago

You can use various approaches, but in this specific case I think you can just

  1. use $global to set a global variable to store the state from the second view
  2. handle the $show event from the first view to check whether the $global state has changed, and act accordingly.

Note that $show is triggered everytime a view is displayed (when the view is first loaded, as well as when the view comes back from a transition)

If you want to handle ONLY when a view comes back from a transition (and not when the view loads for the first time), you can set both $load and $show handlers, where:

{
  "$jason": {
    "head": {
      "title": "..",
      "actions": {
        "$load": { },
        "$show": {
          [YOUR ACTION SEQUENCE]
        }
darenr commented 6 years ago

Would it be possible please to take a look at what I did main: https://jasonbase.com/things/74L2, child https://jasonbase.com/things/5rYe - I'm conditionally reloading if a global.changed is set. I removed the action reload logic to do some "printf" debugging with $util.toast.

Click the "click me"

two return choices that I'd like to work. First is just swiping back and not triggering the conditional $show logic, the second is clicking "set changed" button" which sets a global, then swipe/click back and I'd like to see my conditional $show toast display that it would be reloading/rendering.

Feel free to change those jasonbase examples. The conditional never seems to evaluate to true.

thank you

gliechtenstein commented 6 years ago

There are a couple of problems in the code:

  1. The #if statement should be wrapped in an array. http://docs.jasonette.com/templates/#2-conditional-ifelseifelse In your case it's just an object. This is why the #if is not even triggering to begin with.
  2. After resolving the previous issue, we have another issue. You're setting the $global.changed to "true" (a string value), but then when you return to the first view, under $show you try to check for {{#if $global.changed}}. This expression doesn't work because all expressions inside {{#if}} clause MUST evaluate to true or false boolean. In this case $global.changed would be set to a string value of "true", so it will fail.

What you need is something like this: http://web.jasonette.com/items/220/edit

{
  "$jason": {
    "head": {
      "title": "$href bug",
      "actions": {
        "$pull": {
          "type": "$reload"
        },
        "$show": [
          {
            "{{#if ('changed' in $global) && $global.changed=='true'}}": {
              "type": "$util.toast",
              "options": {
                "text": "would now be refreshing because something changed",
                "type": "note"
              },
              "success": {
                "type": "$global.reset",
                "items": [
                  "changed"
                ]
              }
            }
          }
        ]
      }
    },
    "body": {
      "sections": [
        {
          "items": [
            {
              "type": "label",
              "text": "click me",
              "action": {
                "type": "$href",
                "options": {
                  "url": "http://web.jasonette.com/items/221"
                },
                "success": {
                  "type": "$util.alert",
                  "options": {
                    "title": "back",
                    "description": "hello world"
                  }
                }
              }
            }
          ]
        }
      ]
    }
  }
}
darenr commented 6 years ago

thanks, that makes sense. I had assumed that strings would be cast appropriately, I suppose rather than string=='true' I should just use a boolean value in the $global.set, the array wrapper thing is what got me.