Apollo Client (React): Possible to get normalized data from Query object? - graphql

The Query.data object of react-apollo provides data in a nested form, like so:
{
"findUser": [
{
"__typename": "User",
"id": "5a6efb94b0e8c36f99fba013",
"email": "Lloyd.Nikolaus#yahoo.com",
"posts": [
{
"__typename": "BlogPost",
"id": "5a6efb94b0e8c36f99fba016",
"title": "Dolorem voluptatem molestiae",
"comments": [
{
"__typename": "Comment",
"id": "5a6efb94b0e8c36f99fba019",
"message":
"Alias quod est voluptatibus aut quis sunt aut numquam."
},
{
"__typename": "Comment",
"id": "5a6efb94b0e8c36f99fba01b",
"message": "Harum quia asperiores nemo."
},
{
"__typename": "Comment",
"id": "5a6efb94b0e8c36f99fba01c",
"message": "Vel veniam consectetur laborum."
},
{
"__typename": "Comment",
"id": "5a6efb94b0e8c36f99fba01e",
"message":
"Possimus beatae vero recusandae beatae quas ut commodi laboriosam."
}
]
}
]
}
]
}
I have a use case where I need the data in normalized form, like so:
{
"comments": {
"5a6efb94b0e8c36f99fba019": {
"id": "5a6efb94b0e8c36f99fba019",
"message": "Alias quod est voluptatibus aut quis sunt aut numquam."
},
"5a6efb94b0e8c36f99fba01b": {
"id": "5a6efb94b0e8c36f99fba01b",
"message": "Harum quia asperiores nemo."
},
"5a6efb94b0e8c36f99fba01c": {
"id": "5a6efb94b0e8c36f99fba01c",
"message": "Vel veniam consectetur laborum."
},
"5a6efb94b0e8c36f99fba01e": {
"id": "5a6efb94b0e8c36f99fba01e",
"message":
"Possimus beatae vero recusandae beatae quas ut commodi laboriosam."
}
},
"blogPosts": {
"5a6efb94b0e8c36f99fba016": {
"id": "5a6efb94b0e8c36f99fba016",
"title": "Dolorem voluptatem molestiae",
"comments": [
"5a6efb94b0e8c36f99fba019",
"5a6efb94b0e8c36f99fba01b",
"5a6efb94b0e8c36f99fba01c",
"5a6efb94b0e8c36f99fba01e"
]
}
},
"users": {
"5a6efb94b0e8c36f99fba013": {
"id": "5a6efb94b0e8c36f99fba013",
"email": "Lloyd.Nikolaus#yahoo.com",
"posts": ["5a6efb94b0e8c36f99fba016"]
}
}
}
Seeing as Apollo allready does cache persistance of data in normalized form, is there a way to access the relevant response data in normalized form, without the use of a separate normalizing process like with the graphql-normalizr library?
If possible I'd like to avoid the overhead of double normalization.

You should be able to read the flattened data in the cache with client.readFragment()
Have a look at the documentation here:
https://www.apollographql.com/docs/react/advanced/caching.html#readfragment

Related

Using filter in a Laravel collection

This is the following code:
$apartment_list->filter(function ($apartament) use ($services) {
if (isset($apartament) && $apartament->services[0]->id = $services) {
return $apartament;
}
});
this is an example of my $apartment_list:
{
"id": 1,
"user_id": null,
"title": "Non sunt vitae quia.",
"slug": "non-sunt-vitae-quia",
"rooms": 3,
"bathrooms": 2,
"beds": 11,
"squared_meters": 50,
"address": "14235 Emory Villages Suite 671\nMillerbury, RI 40415-0580",
"latitude": "-75.191525",
"longitude": "-105.046424",
"image": "https://via.placeholder.com/800x800.png/0011aa?text=eveniet",
"is_visible": 1,
"floor": 4,
"price": 1138,
"description": "Dolor fuga cumque delectus doloremque ratione minima. Ut voluptatum porro id et est nam. Dolor unde corrupti excepturi ratione quo.\n\nVoluptatem mollitia omnis ipsa tempore nihil nisi. Ut ullam ut et unde. Est dolores tempore molestiae est omnis.\n\nEst autem ut porro voluptas qui. Ducimus possimus quia vel a beatae id eligendi. Facilis accusamus velit tempora et explicabo architecto. Dolorem at quia esse ipsa officiis est reiciendis.\n\nVoluptate voluptatum minus qui ut velit. Voluptas et quis sint modi culpa. Odit est qui est unde sequi. Eveniet et voluptates est vero.",
"created_at": "2022-02-22T21:26:06.000000Z",
"updated_at": "2022-02-22T21:26:06.000000Z",
"services": [
{
"id": 1,
"name": "WiFi",
"slug": "wifi",
"created_at": "2022-02-22T21:26:06.000000Z",
"updated_at": "2022-02-22T21:26:06.000000Z",
"pivot": {
"apartment_id": 1,
"service_id": 1
}
}
],
"sponsors": []
},
this code simply transform my services id to 1, without doing his job.
how can I fix it?
I'd like to know also how write better $apartament->services[0]->id to have access at my attributes.
Try this one
apartment_list->filter(function ($value, $key) use ($services) {
return $apartament->id === $value->id;
});

How do I get the correct subnode with elasticsearch

I am trying to get specific parts of the data back from a specific document. The document contains product information. This is just a small snippet of the document to explain it better.
"_source": {
"product": {
"code": "AM109",
"stuff": "98989",
"languages": [
{
"language": "en",
"labels": {
"name": "Fusce nulla augue",
"description": "Cras ultricies diam vel orci feugiat ornare. Nulla convallis ligula quis fringilla suscipit. Proin malesuada ligula enim, sit amet semper lorem imperdiet in."
}
},
{
"language": "es",
"labels": {
"name": "Aliquam ut odio quam",
"description": "Nulla pulvinar tortor eu ex vestibulum, nec dictum diam tristique. Pellentesque vitae nibh diam. In id purus at sapien eleifend pulvinar non at velit."
}
}
}
}
The document contains different information for different countries, and labels for different languages. To explain I use the labels.
I need to get the information of the correct product based on the code (product.code), and for the languages it should already only return the labels in the language as requested. E.g. if language es is requested:
"_source": {
"product": {
"code": "AM109",
"stuff": "98989",
"languages": [
{
"language": "es",
"labels": {
"name": "Aliquam ut odio quam",
"description": "Nulla pulvinar tortor eu ex vestibulum, nec dictum diam tristique. Pellentesque vitae nibh diam. In id purus at sapien eleifend pulvinar non at velit."
}
}
}
}
I have tried this with nested options and filters, but I cannot get the correct data returned.
This is an existing system so I cannot make changes to the structure, but I can change the mapping if needed and repopulate the index.
Who can help me with this?
As all documents come with information about all languages and you only search in one language at a given time I suggest the following approach:
Store your documents in language specific indices (advantage: same field names)
You can send your documents always to the same index, but define an ingest pipeline which appends a language-specific suffix such as "_en" to your _index-field, to get your document routed/stored in the language-specific index
Adjust your query to only query the index containing the language
If the last step is not possible, you could define an alias, pointing to all language-specific indices and in your query filter on a field, containing the language-code

Laravel $user->notifications return null

I'm trying to get the notifications for a user. But when i the method get() in my NotificationController start it's always return null. This this the actual code i'm using to debug this feature :
function get(){
$user = \App\User::find(12);
dd($user->notifications);
}
The route is with POST method, i use Postman to test it. I always get error 500 with null content.
Do you know why ?
Thank's in advance
[EDIT]
This is the result of dd($user) for the get() method with POST request :
{
"id": 13,
"rang": 1,
"image": "https://www.drupal.org/files/profile_default.jpg",
"firstname": "Donald",
"lastname": "Torp",
"email": "ashlynn.mcclure#pacocha.com",
"created_at": null,
"updated_at": null
}
This is the content of my DB notifications table actually :
ID : e7f54269-a5ff-4109-9b8a-c2328fb6cf98
Type : App\Notifications\IdeaSelected
notifiable_type : App\Idea
notifiable_id : 13
data : {"idea":{"id":39,"name":"okeefe","description":"Sunt soluta et eum. Vitae sint adipisci et excepturi eos est exercitationem velit. Mollitia hic aut aperiam cum incidunt dolorem sed. Ut blanditiis eos temporibus hic illum quis.","image":"https:\/\/lorempixel.com\/400\/280\/?98265","user":13,"created_at":null,"updated_at":null}}
read_at :
created_at : 2018-04-14 00:57:37
Result for return (dd($user->load('notifications'))); :
#relations: array:1 [
"notifications" => DatabaseNotificationCollection {#549
#items: []
}
]
Result if i change the notifiable_type from App\Idea to App\User :
[
{
"id": "e7f54269-a5ff-4109-9b8a-c2328fb6cf98",
"type": "User::class",
"notifiable_type": "App\\User",
"notifiable_id": 13,
"data": {
"idea": {
"id": 39,
"name": "okeefe",
"description": "Sunt soluta et eum. Vitae sint adipisci et excepturi eos est exercitationem velit. Mollitia hic aut aperiam cum incidunt dolorem sed. Ut blanditiis eos temporibus hic illum quis.",
"image": "https://lorempixel.com/400/280/?98265",
"user": 13,
"created_at": null,
"updated_at": null
}
},
"read_at": null,
"created_at": "2018-04-14 00:57:37",
"updated_at": "2018-04-14 00:57:37"
}
]
Ah i see you are assigning the notifiable_type incorrectly it should say the User::class
When defining the notifiable model think to what you are sending an notification
You should be able to grab the notificationse once you store them in your database.
Take a look at the docs here https://laravel.com/docs/5.6/notifications#database-notifications

Custom analyzer with large char_filter list creation for elasticsearch

I try to add custom analyzer to elastic search. I got a too large "mappings" list of synonyms (mapper_list). Size of mapper_list is about 30.000 elements.
requests.post(es_host + '/_close')
settings = {
"settings" : {
"analysis" : {
"char_filter" : {
"my_mapping" : {
"type" : "mapping",
"mappings" : mapper_list
}
},
"analyzer" : {
"my_analyzer" : {
"tokenizer" : "standard",
"char_filter" : ["my_mapping"]
}
}
}
}
}
requests.put(es_host + '/_settings',
data=json.dumps(settings))
requests.post(es_host + '/_open')
Error messege from elasetic search
[test-index] IndexCreationException[failed to create index]; nested: ArrayIndexOutOfBoundsException[256];
at org.elasticsearch.indices.IndicesService.createIndex(IndicesService.java:360)
at org.elasticsearch.indices.cluster.IndicesClusterStateService.applyNewIndices(IndicesClusterStateService.java:313)
at org.elasticsearch.indices.cluster.IndicesClusterStateService.clusterChanged(IndicesClusterStateService.java:174)
at org.elasticsearch.cluster.service.InternalClusterService.runTasksForExecutor(InternalClusterService.java:610)
at org.elasticsearch.cluster.service.InternalClusterService$UpdateTask.run(InternalClusterService.java:772)
at org.elasticsearch.common.util.concurrent.PrioritizedEsThreadPoolExecutor$TieBreakingPrioritizedRunnable.runAndClean(PrioritizedEsThreadPoolExecutor.java:231)
at org.elasticsearch.common.util.concurrent.PrioritizedEsThreadPoolExecutor$TieBreakingPrioritizedRunnable.run(PrioritizedEsThreadPoolExecutor.java:194)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
Please, any comments about the ways of solving this problem.
Info about ES version:
"version" : {
"number" : "2.4.1",
"build_hash" : "c67dc32e24162035d18d6fe1e952c4cbcbe79d16",
"build_timestamp" : "2016-09-27T18:57:55Z",
"build_snapshot" : false,
"lucene_version" : "5.5.2"
}
I think the cause of the error is due to mapping of large sentences. What exactly you are trying to map? There is a limit of 256 characters if you look at the source code and you are breaching that limit. I get the same exception
ArrayIndexOutOfBoundsException[256]
if I try to map large strings.
{
"settings": {
"analysis": {
"char_filter": {
"my_mapping": {
"type": "mapping",
"mappings": ["More than 256 characters. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. => exception will be thrown"]
}
},
"analyzer": {
"my_analyzer": {
"tokenizer": "standard",
"char_filter": [
"my_mapping"
]
}
}
}
}
}
I do not know your use case but you need to reduce the length of the strings you are mapping, then it should work.

RestKit Custom Data Structure

I need to consume a web service with non-key-differentiated responses like this:
"data": [
{
"type": "sometype",
"id": "1",
"attributes": {
"att1": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam ac dapibus nibh. Nam neque neque, volutpat nec sem ut, hendrerit porta felis.",
"att2": null,
"att3": null,
"att4": null,
"att5": null
}
},
{
"type": "sometype",
"id": "2",
"attributes": {
"att1": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam ac dapibus nibh. Nam neque neque, volutpat nec sem ut, hendrerit porta felis.",
"att2": null,
"att3": null,
"att4": null,
"att5": null
}
},
{
"type": "sometype",
"id": "3",
"attributes": {
"att1": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam ac dapibus nibh. Nam neque neque, volutpat nec sem ut, hendrerit porta felis.",
"att2": null,
"att3": null,
"att4": null,
"att5": null
}
},
]
Where SomeType would be an NSObject or NSManagedObject with an id property, as well as the other 5 att1-5 properties.
Is it possible to consume custom responses like this using RestKit where the response of every call is basically the exact same structure?

Resources