I am working through the elm guide.
In the effects subchapter there is an example with a Time-subscription
subscriptions : Model -> Sub Msg
subscriptions model =
Time.every second Tick
and an example which handles Web-Sockets-subscriptions
subscriptions : Model -> Sub Msg
subscriptions model =
WebSocket.listen "ws://echo.websocket.org" NewMessage
But in these examples, there is only ever one subscription.
How could I handle multiple subscriptions?
You may use Sub.batch, providing a list of subscriptions, it returns a batched subscription
Reference:
Elm 0.19 docs
Pre-0.19 docs
Related
I've been doing some testing with laravel scout and according to the documentation (https://laravel.com/docs/8.x/scout#configuring-searchable-data), I've mapped my User model as such:
/**
* Get the indexable data array for the model.
*
* #return array
*/
public function toSearchableArray()
{
$data = $this->toArray();
return array_merge($data, [
'entity' => 'An entity'
]);
}
Just for the sake of testing, this is literally what I came down to on the debugging.
After importing the User model with this mapping, I can see on the meilisearch dashboard it is indeed showing the user data + the entity = 'An entity'.
However, when applying this:
User::search('something')->where('entity', 'An entity')->get()
It produces the following error:
"message": " --> 1:1\n |\n1 | entity=\"An entity\"\n | ^----^\n |\n = attribute `entity` is not filterable, available filterable attributes are: ",
"exception": "MeiliSearch\\Exceptions\\ApiException",
"file": "/var/www/api/vendor/meilisearch/meilisearch-php/src/Http/Client.php",
Tracing back to view the 'filterable attributes', I've ended at the conclusion that:
$client = app(\MeiliSearch\Client::class);
dump($client->index('users')->getFilterableAttributes()); // Returns []
$client->index('users')->updateFilterableAttributes(['entity']);
dump($client->index('users')->getFilterableAttributes()); // Returns ['entity']
Forcing the updateFilterableAttributes now allows me to complete the search as intended, but I don't feel this should be the regular behaviour? If its mapped on the searchableArray, it should be searchable? What am I not understanding and what other approaches are there to achieve this goal?
This is actually not an issue but a requirement of meilisearch in particular. Scout under the hood uses different drivers for indexing - "algolia", "meilisearch", "database", "collection" and even "null", all of them have different indexing methods unifing of which would be troublesome and inefficient for scout I believe.
So filtering or a faceted search, as meilisearch refers to it, requires us to establish filtering criteria first, which is empty by default for document (models in laravel) fields.
Quoting from the docs:
This step is mandatory and cannot be done at search time. Filters need
to be properly processed and prepared by Meilisearch before they can
be used.
Updating filterableAttributes requires recreating the entire
index. This may take a significant amount of time depending on your
dataset size.
For more info please refer to meilisearch official docs https://docs.meilisearch.com/learn/advanced/filtering_and_faceted_search.html
I am trying to create a messaging system in Django, and I came across an issue: How could I efficiently find all messages linked in a thread?
Let's imagine I have two models:
class Conversation(models.Model):
sender = models.ForeignKey(User)
receiver = models.ForeignKey(User)
first_message = models.OneToOneField(Message)
last_message = models.OneToOneField(Message)
class Message(models.Model):
previous = models.OneToOneField(Message)
content = models.TextField()
(code not tested, I'm sure it wouldn't work as is)
Since it is designed as a simple linked list, is it the only way to traverse it recursively?
Should I try to just get the previous of the previous until I find the first, or is there a way to query all of them more efficiently?
I use Rest Framework serializer with depth. So If you have serializer with Depth value to 3. I will fetch the full model of whatever the foreign key available until three parents.
https://www.django-rest-framework.org/api-guide/serializers/#specifying-nested-serialization
class AppliedSerializer(serializers.ModelSerializer):
class Meta:
model = Applied
fields = ("__all__")
depth = 3
I am using Hop at the moment and I am wondering how you can route to another page outside the main / app module. If you follow the Hop documentation, there are two specific types of messages, well - they are called that in the docs, NavigateTo and SetQuery. How do you raise those messages from sub-modules?
I have tried the following:
view =
button [ onClick (Main.Types.NavigateTo "test") ] []
However, this would mess up the typing.
The problem wasn't with Hop, but my understanding of how parent-child communication works within Elm. To say lightly, you need to be careful for what and when you use this type of communication, but in my case, I read a few good blog posts by Brian Thicks and Alex Lew talking about this form of communication. Especially Alex' post is typical for my use case.
What I did is the following: I added a separate update statement for the type of message I want to route. This is not the best implementation and it can be done more elegantly like Alex describes with the translator pattern.
update msg model =
case msg of
NavigateTo path ->
let
command =
Hop.outputFromPath hopConfig path
|> Navigation.newUrl
in
( model, command )
SetQuery query ->
let
command =
model.address
|> Hop.setQuery query
|> Hop.output hopConfig
|> Navigation.newUrl
in
( model, command )
ExampleMsg InterestingMsg exampleInteger ->
update (NavigateTo "<path here>") model --Update model in let-statement
ExampleMsg subMsg ->
let
( updatedExampleModel, pageCmd ) =
Page.Example.State.update subMsg model.exampleModel
in
( { model | exampleModel = updatedExampleModel }, Cmd.map ExampleMsg pageCmd )
I am trying to learn elm from the past week and want build a simple Hacker News client by calling the official Hacker News API.
I'm calling https: //hacker-news.firebaseio.com/v0/topstories.json to get the top stories which would return an array of story Ids. Once I have the Ids I need to make subsequent calls to https ://hacker-news.firebaseio.com/v0/item/[/* Id goes here */].json fetch the details of each story item.
I have a Main.elm file which would fetch list of top stories.
type Msg = Request
| RequestSuccess (List Int)
| RequestFail Http.Error
update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
case msg of
Request ->
(model, getTopNews)
RequestSuccess list->
(Model list, Cmd.none)
RequestFail error->
(Model [], Cmd.none)
Next part is where I am confused, fetching details for each of the item returned. I also have a NewsItem component to display the details of each news item.
How can I solve this, by creating union types inside NewsItem component(child component) to fetch details? If thats how I should do it..
How can I can call the fetch details api from the NewsItem component as soon as the first api call inside Main.elm is complete?
Or am I missing something obvious here? That's not the correct approach at all?
You can see what I have tried so far here.
Here's my recommendation. It assumes that you'll be loading each NewsItem independently and that they can all fail independently as well. If this isn't the case then we can definitely come up with something that works better for you.
1) Represent your NewsItem not as just a record but a record wrapped in a type to represent the possibility that loading the details could fail. See http://blog.jenkster.com/2016/06/how-elm-slays-a-ui-antipattern.html for more info.
module NewsItem
-- imports and such
type Model = Loading | Success NewsItem | Failure Http.Error
2) Write an init function in your NewsItem module that accepts an Int and returns a (NewsItem.Model, Cmd NewsItem.Msg) pair
init : Int -> (Model, Cmd Msg)
init newsItemId =
( Loading
, getNewsItem newsItemId |> Task.perform GetItemFailure GetItemSuccess
)
3) In your Main module, once you've fetched your list of IDs, map them onto a List (NewsItem.Model, Cmd NewsItem.Msg) using your init function and use the techniques of the Elm architecture to store them as children in your parent model. I recommend storing them as a Dict Int NewsItem.Model which maps ID onto child model.
RequestSuccess list ->
let
children =
list |> List.map (\id -> (id, NewsItem.init id))
childModels =
children
|> List.map (\(id, (model, cmd)) -> (id, model))
|> Dict.fromList
childCmds =
children
|> List.map (\(id, (model, cmd)) -> Cmd.map (NewsItemMsg id) cmd)
|> Cmd.batch
in
(Model childModels, childCmds)
I have a Rails4 app with the following models:
1. Systems (has many devices, has many parameters through devices)
2. Devices (belongs to a system, has many parameters)
3. Parameters (belongs to a Device)
4. Events (polymorphic - Systems, Devices and Parameters can have events)
When an event is created, a boolean field (on the event) is assigned a value. False indicated a failure.
I have a scope on my events, to only show failing events:
scope :failing, -> { where(okay: false).order('created_at desc') }
I can retrieve events as follows:
System.events.failing
Device.events.failing
Parameter.events.failing
I am trying to return a list of Systems where either:
1. the most recent event for the system has failed
2. the most recent event for any of it's devices has failed
3. the most recent event for any parameters of it's devices have failed
I have written this (horrible) SQL query which when executed in the console, returns the systems as an array:
"SELECT * FROM Systems WHERE Systems.id IN (SELECT Devices.system_id FROM Devices WHERE Devices.id IN (SELECT Parameters.device_id FROM Parameters JOIN EVENTS ON Parameters.id=Events.eventable_id WHERE Events.okay ='f')) OR Systems.id IN (SELECT Devices.system_id FROM Devices JOIN Events ON Devices.id=Events.eventable_id WHERE Events.okay='f')")
I need to either define a scope on the System model or a class method to return a list of 'failing' systems. Can you help?
You could mix joins and merges (to merge the WHERE clauses of a scope):
class System
# 1. the most recent event for the system has failed
scope :with_failing_events, -> { joins(:events).merge Event.failing }
# 2. the most recent event for any of it's devices has failed
scope :with_failing_devices, -> { joins(devices: :events).merge Event.failing }
# 3. the most recent event for any parameters of it's devices have failed
scope :with_failing_parameters, -> { joins(devices: { parameters: :events }).merge Event.failing }
end
Notice that passing a hash to joins enables a multiple join, or at least that seems to work in the app I'm working now at (Rails 4.0.5 postgresql).
To filter just the latest event (warning does not work in postgres, untested on other adapters), you could append to this queries:
System.joins(:events).merge(Event.failing).where events: { updated_at: 'MAX("events"."updated_at")' }
In any case, you can merge all these scopes with OR like this:
class System
scope :failing, -> do
where(
[
with_failing_events,
with_failing_devices,
with_failing_parameters
].map(&:where_clauses).join(' OR ')
)
end
end
One option, which would simplify things a bit, would be to add the foreign key, system_id, to the events table. You could then do the following:
Event.where(system_id: [system_id], okay: false).order('created_at DESC')
NOTE: I wouldn't define any relations for this new foreign key, I would simply use it to filter the events table.