Retrofit gson with dynamic keys










0















I've managed to get it to work without a dynamic key. By following this tutorial with this json:



Currently, I'm using Retrofit and trying to get a response with dynamic keys. However, the response body is always null:



enter image description here



This is the response format:




"dynamic1":
"cityID": "id1",
"priceRange": 15
,
"dynamic2":
"cityID": "id2",
"priceRange": 15




In APIUtils.java



 public static CityService getCitiesService() 
return RetrofitClient.getClient(BASE_URL).create(CityService.class);



In CityService.java



public interface CityService 

@GET("/SAGetStrollAwayCity")
Call<CityResponse> getCities();

@GET("/SAGetStrollAwayCity")
Call<CityResponse> getCities(@Query("tagged") String tags);



In CityResponse.java:



public class CityResponse 
/*@SerializedName("results")
@Expose*/ // is this the correct way?
private Map<String, CityDetails> city = new HashMap<>();

public Map<String, CityDetails> getCity()
return city;


public void setCity(Map<String, CityDetails> elemDetails)
this.city = elemDetails;





In CityDetails.java



public class CityDetails 

@SerializedName("cityID")
@Expose
private String cityID;
@SerializedName("priceRange")
@Expose
private Integer priceRange;

public String getCityID()
return cityID;


public void setCityID(String cityID)
this.cityID = cityID;


public Integer getPriceRange()
return priceRange;


public void setPriceRange(Integer priceRange)
this.priceRange = priceRange;





In HomeFragment.java



public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) 
View rootView = inflater.inflate(R.layout.fragment_home, null);
// 2nd api call
mServiceCity = ApiUtils.getCitiesService();
loadCities();

return rootView;


public void loadCities()
mServiceCity.getCities().enqueue(new Callback<CityResponse>()
@Override
public void onResponse(Call<CityResponse> call, Response<CityResponse> response)
// !!! WHY IS THE RESPONSE BODY EMPTY???
if(response.isSuccessful())

// adapter.updateCities(response.body().getCity());

Log.d("MainActivity", "posts loaded from API"+ response.body().getCity());
else
int statusCode = response.code();
// handle request errors depending on status code



@Override
public void onFailure(Call<CityResponse> call, Throwable t)
//showErrorMessage();
Log.d("MainActivity", "error loading from API");


);










share|improve this question
























  • What is the response you are expecting?

    – Ümañg ßürmån
    Nov 14 '18 at 9:02











  • Hi this is the response: "dynamic1": "cityID": "id1", "priceRange": 15 , "dynamic2": "cityID": "id2", "priceRange": 15

    – user1872384
    Nov 14 '18 at 9:03











  • Okay, you mean to say this is not coming, it's always coming empty right?

    – Ümañg ßürmån
    Nov 14 '18 at 9:03











  • Your CityResponse model is wrong as there is no @SerializedName(), how will it know from which key it needs to parse..!!

    – Prashanth Verma
    Nov 14 '18 at 9:06











  • @Ümañgßürmån updated the questions with breakpoint at the response

    – user1872384
    Nov 14 '18 at 9:09















0















I've managed to get it to work without a dynamic key. By following this tutorial with this json:



Currently, I'm using Retrofit and trying to get a response with dynamic keys. However, the response body is always null:



enter image description here



This is the response format:




"dynamic1":
"cityID": "id1",
"priceRange": 15
,
"dynamic2":
"cityID": "id2",
"priceRange": 15




In APIUtils.java



 public static CityService getCitiesService() 
return RetrofitClient.getClient(BASE_URL).create(CityService.class);



In CityService.java



public interface CityService 

@GET("/SAGetStrollAwayCity")
Call<CityResponse> getCities();

@GET("/SAGetStrollAwayCity")
Call<CityResponse> getCities(@Query("tagged") String tags);



In CityResponse.java:



public class CityResponse 
/*@SerializedName("results")
@Expose*/ // is this the correct way?
private Map<String, CityDetails> city = new HashMap<>();

public Map<String, CityDetails> getCity()
return city;


public void setCity(Map<String, CityDetails> elemDetails)
this.city = elemDetails;





In CityDetails.java



public class CityDetails 

@SerializedName("cityID")
@Expose
private String cityID;
@SerializedName("priceRange")
@Expose
private Integer priceRange;

public String getCityID()
return cityID;


public void setCityID(String cityID)
this.cityID = cityID;


public Integer getPriceRange()
return priceRange;


public void setPriceRange(Integer priceRange)
this.priceRange = priceRange;





In HomeFragment.java



public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) 
View rootView = inflater.inflate(R.layout.fragment_home, null);
// 2nd api call
mServiceCity = ApiUtils.getCitiesService();
loadCities();

return rootView;


public void loadCities()
mServiceCity.getCities().enqueue(new Callback<CityResponse>()
@Override
public void onResponse(Call<CityResponse> call, Response<CityResponse> response)
// !!! WHY IS THE RESPONSE BODY EMPTY???
if(response.isSuccessful())

// adapter.updateCities(response.body().getCity());

Log.d("MainActivity", "posts loaded from API"+ response.body().getCity());
else
int statusCode = response.code();
// handle request errors depending on status code



@Override
public void onFailure(Call<CityResponse> call, Throwable t)
//showErrorMessage();
Log.d("MainActivity", "error loading from API");


);










share|improve this question
























  • What is the response you are expecting?

    – Ümañg ßürmån
    Nov 14 '18 at 9:02











  • Hi this is the response: "dynamic1": "cityID": "id1", "priceRange": 15 , "dynamic2": "cityID": "id2", "priceRange": 15

    – user1872384
    Nov 14 '18 at 9:03











  • Okay, you mean to say this is not coming, it's always coming empty right?

    – Ümañg ßürmån
    Nov 14 '18 at 9:03











  • Your CityResponse model is wrong as there is no @SerializedName(), how will it know from which key it needs to parse..!!

    – Prashanth Verma
    Nov 14 '18 at 9:06











  • @Ümañgßürmån updated the questions with breakpoint at the response

    – user1872384
    Nov 14 '18 at 9:09













0












0








0








I've managed to get it to work without a dynamic key. By following this tutorial with this json:



Currently, I'm using Retrofit and trying to get a response with dynamic keys. However, the response body is always null:



enter image description here



This is the response format:




"dynamic1":
"cityID": "id1",
"priceRange": 15
,
"dynamic2":
"cityID": "id2",
"priceRange": 15




In APIUtils.java



 public static CityService getCitiesService() 
return RetrofitClient.getClient(BASE_URL).create(CityService.class);



In CityService.java



public interface CityService 

@GET("/SAGetStrollAwayCity")
Call<CityResponse> getCities();

@GET("/SAGetStrollAwayCity")
Call<CityResponse> getCities(@Query("tagged") String tags);



In CityResponse.java:



public class CityResponse 
/*@SerializedName("results")
@Expose*/ // is this the correct way?
private Map<String, CityDetails> city = new HashMap<>();

public Map<String, CityDetails> getCity()
return city;


public void setCity(Map<String, CityDetails> elemDetails)
this.city = elemDetails;





In CityDetails.java



public class CityDetails 

@SerializedName("cityID")
@Expose
private String cityID;
@SerializedName("priceRange")
@Expose
private Integer priceRange;

public String getCityID()
return cityID;


public void setCityID(String cityID)
this.cityID = cityID;


public Integer getPriceRange()
return priceRange;


public void setPriceRange(Integer priceRange)
this.priceRange = priceRange;





In HomeFragment.java



public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) 
View rootView = inflater.inflate(R.layout.fragment_home, null);
// 2nd api call
mServiceCity = ApiUtils.getCitiesService();
loadCities();

return rootView;


public void loadCities()
mServiceCity.getCities().enqueue(new Callback<CityResponse>()
@Override
public void onResponse(Call<CityResponse> call, Response<CityResponse> response)
// !!! WHY IS THE RESPONSE BODY EMPTY???
if(response.isSuccessful())

// adapter.updateCities(response.body().getCity());

Log.d("MainActivity", "posts loaded from API"+ response.body().getCity());
else
int statusCode = response.code();
// handle request errors depending on status code



@Override
public void onFailure(Call<CityResponse> call, Throwable t)
//showErrorMessage();
Log.d("MainActivity", "error loading from API");


);










share|improve this question
















I've managed to get it to work without a dynamic key. By following this tutorial with this json:



Currently, I'm using Retrofit and trying to get a response with dynamic keys. However, the response body is always null:



enter image description here



This is the response format:




"dynamic1":
"cityID": "id1",
"priceRange": 15
,
"dynamic2":
"cityID": "id2",
"priceRange": 15




In APIUtils.java



 public static CityService getCitiesService() 
return RetrofitClient.getClient(BASE_URL).create(CityService.class);



In CityService.java



public interface CityService 

@GET("/SAGetStrollAwayCity")
Call<CityResponse> getCities();

@GET("/SAGetStrollAwayCity")
Call<CityResponse> getCities(@Query("tagged") String tags);



In CityResponse.java:



public class CityResponse 
/*@SerializedName("results")
@Expose*/ // is this the correct way?
private Map<String, CityDetails> city = new HashMap<>();

public Map<String, CityDetails> getCity()
return city;


public void setCity(Map<String, CityDetails> elemDetails)
this.city = elemDetails;





In CityDetails.java



public class CityDetails 

@SerializedName("cityID")
@Expose
private String cityID;
@SerializedName("priceRange")
@Expose
private Integer priceRange;

public String getCityID()
return cityID;


public void setCityID(String cityID)
this.cityID = cityID;


public Integer getPriceRange()
return priceRange;


public void setPriceRange(Integer priceRange)
this.priceRange = priceRange;





In HomeFragment.java



public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) 
View rootView = inflater.inflate(R.layout.fragment_home, null);
// 2nd api call
mServiceCity = ApiUtils.getCitiesService();
loadCities();

return rootView;


public void loadCities()
mServiceCity.getCities().enqueue(new Callback<CityResponse>()
@Override
public void onResponse(Call<CityResponse> call, Response<CityResponse> response)
// !!! WHY IS THE RESPONSE BODY EMPTY???
if(response.isSuccessful())

// adapter.updateCities(response.body().getCity());

Log.d("MainActivity", "posts loaded from API"+ response.body().getCity());
else
int statusCode = response.code();
// handle request errors depending on status code



@Override
public void onFailure(Call<CityResponse> call, Throwable t)
//showErrorMessage();
Log.d("MainActivity", "error loading from API");


);







android gson retrofit2






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 14 '18 at 9:11







user1872384

















asked Nov 14 '18 at 8:59









user1872384user1872384

4,18553262




4,18553262












  • What is the response you are expecting?

    – Ümañg ßürmån
    Nov 14 '18 at 9:02











  • Hi this is the response: "dynamic1": "cityID": "id1", "priceRange": 15 , "dynamic2": "cityID": "id2", "priceRange": 15

    – user1872384
    Nov 14 '18 at 9:03











  • Okay, you mean to say this is not coming, it's always coming empty right?

    – Ümañg ßürmån
    Nov 14 '18 at 9:03











  • Your CityResponse model is wrong as there is no @SerializedName(), how will it know from which key it needs to parse..!!

    – Prashanth Verma
    Nov 14 '18 at 9:06











  • @Ümañgßürmån updated the questions with breakpoint at the response

    – user1872384
    Nov 14 '18 at 9:09

















  • What is the response you are expecting?

    – Ümañg ßürmån
    Nov 14 '18 at 9:02











  • Hi this is the response: "dynamic1": "cityID": "id1", "priceRange": 15 , "dynamic2": "cityID": "id2", "priceRange": 15

    – user1872384
    Nov 14 '18 at 9:03











  • Okay, you mean to say this is not coming, it's always coming empty right?

    – Ümañg ßürmån
    Nov 14 '18 at 9:03











  • Your CityResponse model is wrong as there is no @SerializedName(), how will it know from which key it needs to parse..!!

    – Prashanth Verma
    Nov 14 '18 at 9:06











  • @Ümañgßürmån updated the questions with breakpoint at the response

    – user1872384
    Nov 14 '18 at 9:09
















What is the response you are expecting?

– Ümañg ßürmån
Nov 14 '18 at 9:02





What is the response you are expecting?

– Ümañg ßürmån
Nov 14 '18 at 9:02













Hi this is the response: "dynamic1": "cityID": "id1", "priceRange": 15 , "dynamic2": "cityID": "id2", "priceRange": 15

– user1872384
Nov 14 '18 at 9:03





Hi this is the response: "dynamic1": "cityID": "id1", "priceRange": 15 , "dynamic2": "cityID": "id2", "priceRange": 15

– user1872384
Nov 14 '18 at 9:03













Okay, you mean to say this is not coming, it's always coming empty right?

– Ümañg ßürmån
Nov 14 '18 at 9:03





Okay, you mean to say this is not coming, it's always coming empty right?

– Ümañg ßürmån
Nov 14 '18 at 9:03













Your CityResponse model is wrong as there is no @SerializedName(), how will it know from which key it needs to parse..!!

– Prashanth Verma
Nov 14 '18 at 9:06





Your CityResponse model is wrong as there is no @SerializedName(), how will it know from which key it needs to parse..!!

– Prashanth Verma
Nov 14 '18 at 9:06













@Ümañgßürmån updated the questions with breakpoint at the response

– user1872384
Nov 14 '18 at 9:09





@Ümañgßürmån updated the questions with breakpoint at the response

– user1872384
Nov 14 '18 at 9:09












1 Answer
1






active

oldest

votes


















2














Personally I'd drop the CityResponse model and just work with Map<String, CityDetails>.



The retrofit interface can then be:



public interface CityService 

@GET("/SAGetStrollAwayCity")
Call<Map<String, CityDetails>> getCities();

@GET("/SAGetStrollAwayCity")
Call<Map<String, CityDetails>> getCities(@Query("tagged") String tags);



In your scenario, the response body is empty because CityResponse would map to a json like:




"city":
"dynamic1":
"cityID": "id1",
"priceRange": 15
,
"dynamic2":
"cityID": "id2",
"priceRange": 15





However, you don't have a root element called city. The json itself can already be mapped to a java Map.



Hope this helps.






share|improve this answer























  • you are a genius!!! What's your payapl account? I'll buy you beer :D

    – user1872384
    Nov 14 '18 at 11:00







  • 1





    :D That's fine, no worries! Glad it helped! Buy the beer to someone else in more need than me :D

    – Fred
    Nov 14 '18 at 11:03










Your Answer






StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













draft saved

draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53296312%2fretrofit-gson-with-dynamic-keys%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









2














Personally I'd drop the CityResponse model and just work with Map<String, CityDetails>.



The retrofit interface can then be:



public interface CityService 

@GET("/SAGetStrollAwayCity")
Call<Map<String, CityDetails>> getCities();

@GET("/SAGetStrollAwayCity")
Call<Map<String, CityDetails>> getCities(@Query("tagged") String tags);



In your scenario, the response body is empty because CityResponse would map to a json like:




"city":
"dynamic1":
"cityID": "id1",
"priceRange": 15
,
"dynamic2":
"cityID": "id2",
"priceRange": 15





However, you don't have a root element called city. The json itself can already be mapped to a java Map.



Hope this helps.






share|improve this answer























  • you are a genius!!! What's your payapl account? I'll buy you beer :D

    – user1872384
    Nov 14 '18 at 11:00







  • 1





    :D That's fine, no worries! Glad it helped! Buy the beer to someone else in more need than me :D

    – Fred
    Nov 14 '18 at 11:03















2














Personally I'd drop the CityResponse model and just work with Map<String, CityDetails>.



The retrofit interface can then be:



public interface CityService 

@GET("/SAGetStrollAwayCity")
Call<Map<String, CityDetails>> getCities();

@GET("/SAGetStrollAwayCity")
Call<Map<String, CityDetails>> getCities(@Query("tagged") String tags);



In your scenario, the response body is empty because CityResponse would map to a json like:




"city":
"dynamic1":
"cityID": "id1",
"priceRange": 15
,
"dynamic2":
"cityID": "id2",
"priceRange": 15





However, you don't have a root element called city. The json itself can already be mapped to a java Map.



Hope this helps.






share|improve this answer























  • you are a genius!!! What's your payapl account? I'll buy you beer :D

    – user1872384
    Nov 14 '18 at 11:00







  • 1





    :D That's fine, no worries! Glad it helped! Buy the beer to someone else in more need than me :D

    – Fred
    Nov 14 '18 at 11:03













2












2








2







Personally I'd drop the CityResponse model and just work with Map<String, CityDetails>.



The retrofit interface can then be:



public interface CityService 

@GET("/SAGetStrollAwayCity")
Call<Map<String, CityDetails>> getCities();

@GET("/SAGetStrollAwayCity")
Call<Map<String, CityDetails>> getCities(@Query("tagged") String tags);



In your scenario, the response body is empty because CityResponse would map to a json like:




"city":
"dynamic1":
"cityID": "id1",
"priceRange": 15
,
"dynamic2":
"cityID": "id2",
"priceRange": 15





However, you don't have a root element called city. The json itself can already be mapped to a java Map.



Hope this helps.






share|improve this answer













Personally I'd drop the CityResponse model and just work with Map<String, CityDetails>.



The retrofit interface can then be:



public interface CityService 

@GET("/SAGetStrollAwayCity")
Call<Map<String, CityDetails>> getCities();

@GET("/SAGetStrollAwayCity")
Call<Map<String, CityDetails>> getCities(@Query("tagged") String tags);



In your scenario, the response body is empty because CityResponse would map to a json like:




"city":
"dynamic1":
"cityID": "id1",
"priceRange": 15
,
"dynamic2":
"cityID": "id2",
"priceRange": 15





However, you don't have a root element called city. The json itself can already be mapped to a java Map.



Hope this helps.







share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 14 '18 at 10:46









FredFred

8,34512644




8,34512644












  • you are a genius!!! What's your payapl account? I'll buy you beer :D

    – user1872384
    Nov 14 '18 at 11:00







  • 1





    :D That's fine, no worries! Glad it helped! Buy the beer to someone else in more need than me :D

    – Fred
    Nov 14 '18 at 11:03

















  • you are a genius!!! What's your payapl account? I'll buy you beer :D

    – user1872384
    Nov 14 '18 at 11:00







  • 1





    :D That's fine, no worries! Glad it helped! Buy the beer to someone else in more need than me :D

    – Fred
    Nov 14 '18 at 11:03
















you are a genius!!! What's your payapl account? I'll buy you beer :D

– user1872384
Nov 14 '18 at 11:00






you are a genius!!! What's your payapl account? I'll buy you beer :D

– user1872384
Nov 14 '18 at 11:00





1




1





:D That's fine, no worries! Glad it helped! Buy the beer to someone else in more need than me :D

– Fred
Nov 14 '18 at 11:03





:D That's fine, no worries! Glad it helped! Buy the beer to someone else in more need than me :D

– Fred
Nov 14 '18 at 11:03



















draft saved

draft discarded
















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid


  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53296312%2fretrofit-gson-with-dynamic-keys%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







這個網誌中的熱門文章

What does pagestruct do in Eviews?

Dutch intervention in Lombok and Karangasem

Channel Islands