precept 2018-03-12

Hey @amarjeet. Let me take a look

šŸ‘ 1

First thing that comes to mind is perhaps the user is already logged in? e.g. :loggedIn fact already exists

Looks like the view might not permit login when loggedIn is true though…

no, :user/loggedIn fact is getting inserted for the first time

šŸ‘ 1

Can you clarify what data doesn’t exist and how you’re able to detect this?

I’m thinking you’re looking for this:

{:db/id (:id %)
                           :user/name (:name %)
                           :user/email (:email %)
                           :user/membershipId (:membershipId %)
                           :user/loggedIn true})
but I don’t see rules or subscrtptions that deal with these fields apart from authentication-successful which matches on :user/loggedIn

At a high level things should work as you described and I can’t see anything that would cause them not to

I assumed it because when I fire the authentication-successful rule without [[?user :user/loggedIn true]] , the `:home-page gets rendered

I am using these subs, also, the API is working - have checked them separetly

Hm. Well, a rule shouldn’t fire unless all its conditions are true. I might try changing [[?user :user/loggedIn true]] to

[?the-fact <- [?user :user/loggedIn true]]
and logging ?the-fact if you haven’t

let me try this

Nice. This all looks great

I’d consider using insert! instead of insert-unconditional! wherever you can. It’s not clear whether you’re retracting facts elsewhere though (in which case insert-unconditional! is your friend)

I’m not confident that’s related to the problem you’re experiencing, just something I noticed

So, its really strange that the rule with [[?user :user/loggedIn true]] alone is getting fired. But, its not getting fired when other conditions are put in - ex: it didn't fire with [?the-fact <- [?user :user/loggedIn true]] as well - I don't see anything printed in the console

sorry, with [[?state :state/current-state :login-progress]] alone

I dont see anything printed if i add [?the-fact <- [?user :user/loggedIn true]] condition

and then log ?the-fact

So, even if [?user :user/loggedIn true] doesn't exist, ?the-fact should log something right?

If I understand correctly, no. If the right hand side of the rule fires, then all the rule’s conditions are true.

that means, the fact doesn't exist at the time of firing that rule

does it have to do something with then?

?the-fact binds to the value of whole fact that matches [?user :user/loggedIn true]

Can you log ?user when the rule fires?

Because if the rule fires you should be able to log that as well as [?the-fact <- ...]

let me check again

No, its not getting logged - rule is not getting fired with user fact condition

It seems like something with then

when it inserts user fact at the time of api response

Try removing ā€œtrueā€ from the condition. Maybe the else case of your if statement is evaluating?

So, the steps are: when I click on login button, state changes to :login-progress, and api call happens, which should have inserted user fact - these to combined, should fire the rule in question

It could be a problem with then but I’m not sure how. The fullstack examples and other work I’m doing use the same pattern you’re using

hmm, let me try removing the true condition

By doing that it should pick up a :user/loggedIn with anything in the value slot

the rule fires with ?user value null

Kind of a side note but you can also see the state of the rules session at the end of each fire rules with @precept.state/store

@precept.state/store this should help in debugging

Ok. So I’m guessing line 14 of your snippet is running instead of line 9

actually no, I have tested with different set of rules - that is working fine. But, even with the 2nd condition, the ?user can't be null, because the fact is inserted with some id

Hm. Well, I’m guessing the reason the rule is firing now is because there’s a :user/loggedIn fact that has a value slot of false. That would explain why previously when the condition only matched on the value true the rule wasn’t firing

So you could try [?my-fact <- [?user :user/loggedIn]] and print the result of ?my-fact

yes, it is firing with false as well

And hopefully it will be {:e nil :a :user/loggedIn :v false :t some number}. Otherwise I’m lost

Ok. Do you insert :user/loggedIn false anywhere else?

I do get {:e nil :a :user/loggedIn :v false :t some number} kind of result

its pretty weired

:user/loggedIn is getting inserted only at the time of that api call

The other strange thing is - if you see in the app return value, along with the :user/loggedIn false, it also inserted id, so why are we getting id as nil?

in the api return value

(defn auth [email password]
  (GET "")
       {:params {:email email
                 :password password}
        :handler #(if (:login-status %)
                    (then {:db/id (:id %)
                           :user/name (:name %)
                           :user/email (:email %)
                           :user/membershipId (:membershipId %)
                           :user/loggedIn true})
                    (then {:db/id (:id %)
                           :user/loggedIn false}))
        :error-handler #(.log js/console %)}))
What’s the % / result you’re getting here?

I printed %, and I got {:login-status true, :id 17592186045436, :name "Test User", :email "<mailto:test@gmail.com|test@gmail.com>", :membershipId "m0"}

Well…hm. What happens when you do:

#(if (:login-status %)
                    (then {:db/id (:id %)
                           :user/name (:name %)
                           :user/email (:email %)
                           :user/membershipId (:membershipId %)
                           :user/loggedIn true})
                    (then {:db/id (:id %)
                           :user/loggedIn false}))

Sorry one min

So, i just tested with a hard-coded :db/id (ex: 2345), and now it returns :id as 2345, but with value false

this is interesting šŸ™‚

Sorry. Basically I’m not convinced that’s the result 😊 it could be that then isn’t parsing Booleans in maps correctly

hmm, i will just quickly use string and check

doesn't look like its a boolean parsing error, I am getting same results with string as well

#(let [login-status (:login-status %)
          id (:id %)
          _ (println "Login status for id!" login-status id)
          (if login-status
            (let [facts [[id :user/name (:name %)]
                             [id :user/email (:email %)]
                             [id :user/membershipId (:membershipId %)]
                             [id :user/loggedIn true]]
                    (then facts))
           (let [facts [[id :user/loggedIn false]]
              (then facts))

Sorry for the formatting and probably wrong parens…

But if you could try that, it should show whether the response is what you expect and also circumvent any bugs pertaining to maps by using the vector format instead

ites pretty weird, I am getting Login status for id! nil nil - so both login-status and id are nil

I am changing my back-end response type for login-status to string. Just a sec

Is the response being parsed as EDN?

This is my response map

`{:login-status "true" :id user-id :name user-name :email stored-email :membershipId membershipId}`

changing login-status to string didnt help

same result

its ring/response

Hm. Ok. Well, I think if you can get (:login-status) of the response to not be nil nil then everything else should work, with the rules the way you had originally

yeah, i think I will try the api call with cljs-http once

Ok. Let me know how it works out or if I can be of any help

holy cow šŸ˜„

it worked with cljs-http response

yeah, super strange

this is working

Not sure what happened with Ajax

Anyway, a big thanks to you - you spent over one n half an hr with me on this. Really really appreciate it šŸ™‚

now I can sleep well

Of course. Thanks for sharing your code. Looks really good šŸ™‚

šŸ‘ 1