113
Views
19
Comments
Solved
Dropdown search from REST API - Cannot deserialize the current JSON object
Application Type
Reactive

Hi everyone,

I am building a form where I would like to have one widget where I can pull a list of names from a REST API, with an autocomplete function where the user can refine the list as they are typing.

I am trying to set this up by using the DropdownSearch (Reactive application). Is it the right element to use?

I am assuming it is and here is what I have set up for now:

I have added the REST API method to retrieve this users' list.

Here is the structure:

It's quite straightforward, I am passing a value (the user name, either first or last name) and I will get a list in return.

The list looks like this:

{

  "is_error": 0,

  "version": 3,

  "count": 2,

  "values": [

    {

      "contact_id": "123",

      "contact_type": "Individual",

      "contact_sub_type": "",

      "sort_name": "Test, User",

      "display_name": "Mr User Test",

      "do_not_email": "0",

      "do_not_phone": "0",

      "do_not_mail": "0",

      "do_not_sms": "0",

      "do_not_trade": "0",

      "is_opt_out": "0",

      "legal_identifier": "",

      "external_identifier": "",

      "nick_name": "",

      "legal_name": "",

      "image_URL": "",

      "preferred_communication_method": "",

      "preferred_language": "en_US",

      "preferred_mail_format": "Both",

      "first_name": "User",

      "middle_name": "",

      "last_name": "Test",

      ........all the other fields

    },

    {

      "contact_id": "124",

      ....all the other fields

    }

  ]

}


Outsystems generated two structures linked to the REST API: one with the API call fields (Is_error, Version, Count) and another one with all the values of the users (everything inside values).

Here is how I tried to set it up:

  1. In the screen where I want the form I created a "fetch data from other sources" action
  2. I have modified the output data type of the action to be "GetUsersData List"
  3. Inside the action, I have dragged and dropped the "GetRest" action 
  4. I have added a simple Assign where I assign the values coming from the API call to the action's output parameter
  5. At this point I have added a dropdown search in the screen, assigned the option list to outputparameter and choose the fields that I want as value and label.


I though it would be enough to show the data but I get an error:

Failed to parse response of the method 'GetRest' of the '...' REST API:
Parsing 'values.16261': Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'ssAtlas.CcStageCommunityItattiHarvard+RESTCiviCRMUserDetails[]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List<T>) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.
Path 'values.16261', line 1, position 55.

I have found other posts where it was suggested to use the JSON deserialize but in everything I have tried, I am always getting the same result. 

Thanks a lot in advance and sorry for the long post.

Andrea

2023-03-16 16-29-51
Paulo Rosário
Solution

Ok, let's try something else . 

Follow this post on how to increase the logging for APIs. With this active, you should be able to check the HTTP trace to see what information is being passed.

With that hopefully, we can figure out what's happening. 

UserImage.jpg
vikas sharma
Champion

what is the databype of values. 

UserImage.jpg
Andrea Caselli

Do you mean the datatype of the values inside "Values" (that would be "text") or the datatype of "Values" (that would be GetUsersData List)

UserImage.jpg
vikas sharma
Champion

could you provide oml for this.

UserImage.jpg
Andrea Caselli

Unfortunately, I can't Vikas as the API comes from an internal CRM. I can post more information though...

UserImage.jpg
vikas sharma
Champion

You already posted in detail, it seems only response structure issue the values from API are not getting mapped correctly with structure. 

As i asked datatype of values, so it should be list of GetUserData. Then I think it will work.

UserImage.jpg
Andrea Caselli

Thank you Vikas. The output parameter is already a list of GetUserData but I am still getting an error.

Should I try to loop through the GetRest response and assign only a couple of fields that I need (like first, last name and contact id)?

How do I check what is the exact JSON that Outsystems is receiving?

UserImage.jpg
vikas sharma
Champion

I think you should check with minimum fields first then increase fields after success. 

Also if you can't share as API is from internal CRM. Could you please share oml and complete response of API. So will use that response for mapping.

regards


UserImage.jpg
Andrea Caselli

Sure! I will create a brand new oml and will try to simplify things as much as possible.

UserImage.jpg
Andrea Caselli

Here is the oml and now I will try to share the JSON result when passing a blank value, which is what I am doing as the first step.

DropdownListOfUsersFromAPI.oml
UserImage.jpg
Andrea Caselli

Hi @Vikas Sharma 

Here is the JSON response.

This is the response I am seeing when I have added the REST API method, but how do I check the exact response?

JSON Response.docx
2023-03-16 16-29-51
Paulo Rosário

Hello Andrea, 

Could it be that one of the fields in Values returned by the API should be a list? 

I noticed that there is no list on your structure and the error states that there should be one to be able to parse the information correctly.

Hope it helps! 

Paulo Rosário

UserImage.jpg
Andrea Caselli

Hi Paulo,

Thank you for the tip.

I have created another REST API and filtered the fields to return (from the URL path) and made it as simple as possible (contact id, first and last name).

Now I get the following error:

Failed to parse response of the method 'GetRest2' of the '...' REST API:
Parsing '': Unexpected character encountered while parsing value: <. Path '', line 0, position 0.



2023-03-16 16-29-51
Paulo Rosário
Solution

Ok, let's try something else . 

Follow this post on how to increase the logging for APIs. With this active, you should be able to check the HTTP trace to see what information is being passed.

With that hopefully, we can figure out what's happening. 

UserImage.jpg
Andrea Caselli

@Paulo Rosário 👨🏽‍🚀  Wow! Thank you so much. That is a super useful post that I will bookmark straight away!

I have downloaded the HTTP trace and noticed a few weird things straight away.

There are missing parts in the GET call and it's passing back an XML result, not JSON!

I have added the GET method URL as follows:

https://test.com/sites/something/something/rest.php?entity=Contact&action=get&api_key=123&key=123&json=%7B%22sequential%22:1,%22sort_name%22:%7B%22LIKE%22:%22{name}%22%7D%7D


Inside the HTTP trace, it looks like this: https://test.com/sites/something/something/rest.php?entity=Contact&action=get&api_key=123&key=123


So the URL is cut out! it didn't pass the json parameter and therefore the API gave an XML back (and unfortunately not an error so I couldn't tell straight away that something was wrong).

I have escaped the curly brackets because Outsystems doesn't accept them twice (I guess they are reserved to indicate a variable). Could that be the problem?


2023-03-16 16-29-51
Paulo Rosário

Progress!

Without seeing the API call I can't be sure, but there is only one way to find out, and that is to try it out .

Now that you can see the trace it should be easier to troubleshoot. 

Do you have a successful call using Postman or similar software? If so you can compare booth.

UserImage.jpg
Andrea Caselli

In Postman everything works fine. 

The problem is passing and escaping the parameter

This is the bit the Outsystems cuts out:

&json={"sequential":1,"sort_name":{"LIKE":"test"}}

where test is the user input

I have tried to build it this way:

%7B%22sequential%22:1,%22sort_name%22:%7B%22LIKE%22:%22{name}%22%7D%7D


EDIT: Progress!

I managed to make the API work for sending a default value "%7B%22sequential%22:1,%22return%22:%22id,first_name,last_name%22,%22sort_name%22:%7B%22LIKE%22:%22test%22%7D%7D"

I guess I can build the parameter by concatenation but how do I programmatically pass what the user is typing? I don't see a variable in the dropdown search.

2023-03-16 16-29-51
Paulo Rosário

That's great! 

A Dropdown Search applies your search (variable ) to an already existing list ( from your API ), so if your aim is to simply filter by the name there is no need to add the filter parameter to the API because you will be able to filter with the widget.

So can just retrieve all your information and filter that way.

Now if the API returns a ton of information that can slow down your app then a variable is really necessary in order to avoid performance issues.   

Sadly I don't know of a way to update the list on a Dropdown Search dynamically.

UserImage.jpg
Andrea Caselli

Thank you so much Paulo!

I was finally able to get the full list from the API and it slows down only a bit and I think it won't be noticeable to the end user. I am still interested in knowing if there is a way to pass the user input. 

2023-03-16 16-29-51
Paulo Rosário

Glad to hear it! 

Maybe in the future someone will figure it out :) 


Community GuidelinesBe kind and respectful, give credit to the original source of content, and search for duplicates before posting.