Is it possible to render a component during eval in halogen? - purescript

In my halogen project have this eval branch:
eval (SetTest tName next) = do
H.set (State Nothing)
detail <- H.fromAff $ toAff settings $ getTestsByTestname (tName ^. unTestName)
H.set (State (Just detail))
pure next
The toAff bit if off doing AJAX and may take a while to return. In my render function I have
, case ts of
Nothing ->
HH.div [class_ BS.centerBlock]
[HH.i [classes (HH.className <$> ["fa", "fa-spinner", "fa-spin", "loading"])]
[]
]
Just td ->
HH.h3_ [HH.text $ td ^. tdName<<<unTestName]
I'm naively expecting to see a loading spinner when until my aff action returns, but it looks like the eval runs all the way through before the html is rendered. Is this correct?
edit
Turns out this was user error - I was calling my Query in wrong order. Future mes: setting the state does indeed update the ui :-)

No, modifying the state during eval should indeed trigger a render. Unless your Aff isn't really async, I'm not sure why you wouldn't be seeing what you expect here.
Have you tried doing something like H.fromAff $ later' 5000 $ pure <some value>? Where later' comes from Control.Monad.Aff and <some value> is something suitable for detail. You should see the loading spinner for 5 seconds then, before it resolves to <some value>.

Related

python click passing multiple key values as options

I am using python-click and I would like to pass values with a format like this
myprogram mycommand --parameter param1=value1 --parameter param2=value2
I was looking at click option documentation but I can't find any construct that could help with this, the only solution I can find is invoking a callback function and check that the string is properly constructed <key>=<value>, then elaborate the values properly.
Nothing bad in that solution, but I was wondering if there is a more elegant way to handle this since the pattern looks to be common enough.
So, I've had a go at it. I've managed to do it the following ways.
Firstly, I've tried this, though it doesn't satisfy the --parameter criteria.
#click.command("test")
#click.argument("args", nargs=-1)
def test(args):
args = dict([arg.split("=") for arg in args])
print(args)
so when invoking like test param1=test1 param2=test the output is:
{'param1': 'test1', 'param2': 'test2' }
Secondly, I thought about a multiple option, combined with a variadic argument, which seems to be closer to your requirements:
test -p param1=test -p param2=test
#click.command("test")
#click.option('-p', '--parameter', multiple=True)
#click.argument("args", nargs=-1)
def test(*args, **kwargs):
param_args = kwargs['parameter']
param_args = dict([p.split('=') for p in param_args])
print(param_args)
if __name__ == '__main__':
test()
The output will be the same as the previous case.
If you were to print(kwargs['parameter']), you'd get
('param1=test', 'param2=test')
It sounds a bit more cleaner than using a callback, but not by much. Still, hope it helps.

What if there exists no matched rule in a Lex program because of REJECT?

I'm currently reading the documentation on Lex written by Lesk and Schmidt, and get confused by the REJECT action.
Consider the two rules
a[bc]+ { ... ; REJECT;}
a[cd]+ { ... ; REJECT;}
Input:
ab
Only the first matches, and see what we get from the material.
The action REJECT means ``go do the next alternative.'' It causes whatever rule was second choice after the current rule to be executed.
However, there is no second choice, will there comes a error?
There are really very few use cases for REJECT; I don't think I've ever seen an instance of it in use other than in examples.
Anyway, unless you specify %option nodefault (or the -s command-line flag), flex will add a default fallback action to your ruleset, equivalent to
.|\n ECHO;
In your case, that pattern will match after the REJECT.
However, it is possible to override the default action; for example, you could add the rule:
.|\n REJECT;
In that case, flex really will not have an alternative after the two REJECTs, and it will print an error message on stderr ("flex scanner jammed") and then call exit.

How to remove a Aff (similar to Eff's unsafePerformEff)?

I am trying to get hold of some files content I read from a file via Node.FS.Aff.readTextFile so using asynchrous effects.
However my question is more general.
myFile::forall r. String -> Aff ( fs :: FS | r) (Either Error String)
myFile file = attempt $ readTextFile Node.Encoding.UTF8 file
So I want to get at the Left or Right value. If it where Eff instead of Aff I could use
let x = unsafePerformEff $ myFile "someFile.txt"
Thanks
You should never try to "get at" the value by using unsafePerformEff, as such is truly unsafe and will introduce serious bugs into any larger code base.
Instead, you can use do notation to "get at" the values. For example:
do
result <- attempt $ readTextFile Node.Encoding.UTF8
case result of
Left error -> ...
Right file -> ...
...
Note that there exists no unsafePerformAff, because the computation is asynchronous, and there is no way to block in Javascript runtimes.

Erlang mnesia equivalent of "select * from Tb"

I'm a total erlang noob and I just want to see what's in a particular table I have. I want to just "select *" from a particular table to start with. The examples I'm seeing, such as the official documentation, all have column restrictions which I don't really want. I don't really know how to form the MatchHead or Guard to match anything (aka "*").
A very simple primer on how to just get everything out of a table would be very appreciated!
For example, you can use qlc:
F = fun() ->
Q = qlc:q([R || R <- mnesia:table(foo)]),
qlc:e(Q)
end,
mnesia:transaction(F).
The simplest way to do it is probably mnesia:dirty_match_object:
mnesia:dirty_match_object(foo, #foo{_ = '_'}).
That is, match everything in the table foo that is a foo record, regardless of the values of the fields (every field is '_', i.e. wildcard). Note that since it uses record construction syntax, it will only work in a module where you have included the record definition, or in the shell after evaluating rr(my_module) to make the record definition available.
(I expected mnesia:dirty_match_object(foo, '_') to work, but that fails with a bad_type error.)
To do it with select, call it like this:
mnesia:dirty_select(foo, [{'_', [], ['$_']}]).
Here, MatchHead is _, i.e. match anything. The guards are [], an empty list, i.e. no extra limitations. The result spec is ['$_'], i.e. return the entire record. For more information about match specs, see the match specifications chapter of the ERTS user guide.
If an expression is too deep and gets printed with ... in the shell, you can ask the shell to print the entire thing by evaluating rp(EXPRESSION). EXPRESSION can either be the function call once again, or v(-1) for the value returned by the previous expression, or v(42) for the value returned by the expression preceded by the shell prompt 42>.

Why would value passed through $m->comp() lose its value irregularly?

I have a perl mason component which is called to display an html page containing threaded comments. It uses Class DBI for loading from a MySQL database.
The problem is that sometimes, and I mean sometimes, very irregularly a variable loses its value partway through the code. I am not changing the code between when it starts and stops happening, just reloading the page. It's not even that it just has the value on one page load and not the next. It's that on one page load you can print something to show that the variable contains a ref to an object (a "Person" with a name, etc.) and later on in the code on that same page load you can print that again and show that it doesn't. On the next page load the variable may retain its value all the way through. The only thing that is happening is that the variable gets passed through a call to $m->comp(), and a default gets applied if it is empty.
Further, it happens for each and every comment, effectively losing its value many times in the same page load.
Unfortunately (or fortunately, depending on how you look at it) I can't post all the code involved verbatim, but it boils down to the following, note the two commented lines marked "HERE":
<%init>
my #comments = $dc->document->search("type = 'comment'");
</%init>
<div>
<& '.comments', all_comments => \#comments &>
</div>
<%def .comments>
<%args>
$all_comments
</%args>
<%init>
my #comments;
#comments = #$all_comments;
</%init>
% for my $c (#comments) {
% my $poster = p($c->get_value('poster'));
% $poster = Person->get_anonymous unless ref $poster;
% # HERE: The variable is a ref to a given Person.
% $m->comp('.comment', poster => $poster);
% }
</%def>
<%def .comment>
<%args>
$poster => Person->get_anonymous
</%args>
<%init>
# HERE: The variable is now the result of Person->get_anonymous instead.
unless (ref $poster) {
$poster = Person->get_anonymous;
}
</%init>
<p><% $poster->id == 1 ? ' (anonymous)' : $poster->fullname %></p>
</%def>
I've tried removing that default, in which case I get an empty variable.
This is a years old problem scrutinized down to these few lines of code where, programmatically speaking, something impossible seems to be happening. I'm left with a possible bug in Mason, or maybe some combination of things like some voodoo between Class DBI and the database losing a connection, or something I don't know about $m->comp().
The only other clue I have is that when I've added something to the page, I've had the problem show up to an entirely new variable. Unfortunately, I never know when the problem is going to happen, and it happens seldom enough that I won't be able to go throw some suggested debugging code into it that will immediately give me something to report back. I'm only hoping for the off chance that somebody has experienced something similar or knows some possible problem that might explain what is going on.