Why do I get an empty response when my android app calls my API on my server?
Asked Answered
S

5

5

I have android application that called information and show it as a list.

I have a spinner when you choose the date from the spinner you get the information related to that date.

In the app first load it calls automatically today information.

this is the code I use in my main activity to create my spinner and fill it with elements and handle the clicks on each item:

// Spinner element
spinner = (Spinner) v.findViewById(R.id.spinner);

// Spinner click listener
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
      public void onItemSelected(AdapterView<?> parent, View view,
                                       int position, long id) {
                // On selecting a spinner item
                //String item = parent.getItemAtPosition(position).toString();
                switch(position){
                    case 3:
                        if (JsonUtils.isNetworkAvailable(getActivity())) {
                            list.clear();
                            new MyTask().execute(Config.SERVER_URL + "/banko_api.php?d_o=-1");
                        } else {
                            Toast.makeText(getActivity(), getResources().getString(R.string.failed_connect_network), Toast.LENGTH_SHORT).show();
                        }
                        break;
                    case 4:
                        if (JsonUtils.isNetworkAvailable(getActivity())) {
                            list.clear();
                            new MyTask().execute(Config.SERVER_URL + "/banko_api.php?d_o=0");
                        } else {
                            Toast.makeText(getActivity(), getResources().getString(R.string.failed_connect_network), Toast.LENGTH_SHORT).show();
                        }
                        break;
                    case 5:
                        if (JsonUtils.isNetworkAvailable(getActivity())) {
                            list.clear();
                            new MyTask().execute(Config.SERVER_URL + "/banko_api.php?d_o=1");
                        } else {
                            Toast.makeText(getActivity(), getResources().getString(R.string.failed_connect_network), Toast.LENGTH_SHORT).show();
                        }
                        break;
                    default:
                        if (JsonUtils.isNetworkAvailable(getActivity())) {
                            list.clear();
                            new MyTask().execute(Config.SERVER_URL + "/banko_api.php?d_o=0");
                        } else {
                            Toast.makeText(getActivity(), getResources().getString(R.string.failed_connect_network), Toast.LENGTH_SHORT).show();
                        }
                        break;
                }
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {

            }
        });



        Calendar calendar = Calendar.getInstance();
        Date today = calendar.getTime();

        calendar.add(Calendar.DAY_OF_YEAR, -1);
        Date yesterday = calendar.getTime();

        calendar = Calendar.getInstance();

        calendar.add(Calendar.DAY_OF_YEAR, 1);
        Date tomorrow = calendar.getTime();


        DateFormat dateFormat = new SimpleDateFormat("dd/MM EEE");
        String todayAsString = dateFormat.format(today);
        String tomorrowAsString = dateFormat.format(tomorrow);
        String yesterdayAsString = dateFormat.format(yesterday);


        // Spinner Drop down elements
        List<String> categories = new ArrayList<String>();

        categories.add(yesterdayAsString);
        categories.add(todayAsString);
        categories.add(tomorrowAsString);

        // Creating adapter for spinner
        ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(getContext(), R.layout.spinner_item, categories);


        dataAdapter.setDropDownViewResource(R.layout.spinner_dropdown_item);
        // attaching data adapter to spinner

        spinner.setAdapter(dataAdapter);

        spinner.setSelection(4);

The problem : first load of the app is calling the data of today (which is the default choice in my spinner) without any problem. if i choose another element in the spinner it also calls the related data without problem. now if I want to select back today element in the spinner no data will be brought from the server even when the app at the start up it calls data from the same link and get it.

I get this message in my log : W/System.err: org.json.JSONException: Value [] of type org.json.JSONArray cannot be converted to JSONObject

The onPostExcute of my Asynktask contains this code:

@Override
        protected void onPostExecute(String result) {
            super.onPostExecute(result);

            if (null != progressDialog && progressDialog.isShowing()) {
                progressDialog.dismiss();
            }

            if (null == result || result.length() == 0) {
                Toast.makeText(getActivity(), getResources().getString(R.string.failed_connect_network), Toast.LENGTH_SHORT).show();
            } else {

                try {
                    Log.d("resultTT",result);
                    JSONObject mainJson = new JSONObject(result);
                    JSONArray jsonArray = mainJson.getJSONArray(JsonConfig.CATEGORY_ARRAY_NAME);
                    JSONObject objJson = null;
                    for (int i = 0; i < jsonArray.length(); i++) {

                        objJson = jsonArray.getJSONObject(i);
                        ItemMatch objItem = new ItemMatch();
                        objItem.setMatchId(objJson.getString(JsonConfig.Match_ID));
                        objItem.setMatchTournamentName(objJson.getString(JsonConfig.Match_LEAGUE_NAME));
                        objItem.setMatchTime(objJson.getString(JsonConfig.Match_TIME));
                        objItem.setMatchStatus(objJson.getString(JsonConfig.Match_STATUS));
                        objItem.setMatchLocalTeamName(objJson.getString(JsonConfig.Match_LOCALTEAM_NAME));
                        objItem.setMatchVisitorTeamName(objJson.getString(JsonConfig.Match_VISITORTEAM_NAME));
                        objItem.setMatchLocalTeamGoals(objJson.getString(JsonConfig.Match_LOCALTEAM_GOALS));
                        objItem.setMatchVisitorTeamGoals(objJson.getString(JsonConfig.Match_VISITORTEAM_GOALS));
                        objItem.setMatchBestOddPercent(objJson.getString(JsonConfig.Match_BEST_ODD_PERCENT));
                        objItem.setMatchBestOddResult(objJson.getString(JsonConfig.Match_BEST_ODD_RESULT));
                        list.add(objItem);
                    }

                } catch (JSONException e) {
                    e.printStackTrace();
                }


                for (int j = 0; j < list.size(); j++) {
                    object = list.get(j);

                    array_match_id.add(String.valueOf(object.getMatchId()));
                    str_match_id = array_match_id.toArray(str_match_id);

                    array_league_name.add(String.valueOf(object.getMatchTournamentName()));
                    str_league_name = array_league_name.toArray(str_league_name);

                    array_match_time.add(String.valueOf(object.getMatchTime()));
                    str_match_time = array_match_time.toArray(str_match_time);

                    array_match_status.add(String.valueOf(object.getMatchStatus()));
                    str_match_status = array_match_status.toArray(str_match_status);

                    array_match_localteam_name.add(object.getMatchLocalTeamName());
                    str_match_localteam_name = array_match_localteam_name.toArray(str_match_localteam_name);

                    array_match_visitorteam_name.add(object.getMatchVisitorTeamName());
                    str_match_visitorteam_name = array_match_visitorteam_name.toArray(str_match_visitorteam_name);

                    array_match_localteam_goals.add(object.getMatchLocalTeamGoals());
                    str_match_localteam_goals = array_match_localteam_goals.toArray(str_match_localteam_goals);

                    array_match_visitorteam_goals.add(object.getMatchVisitorTeamGoals());
                    str_match_visitorteam_goals = array_match_visitorteam_goals.toArray(str_match_visitorteam_goals);

                    array_match_best_odd_percent.add(object.getMatchBestOddPercent());
                    str_match_best_odd_percent = array_match_best_odd_percent.toArray(str_match_best_odd_percent);

                    array_match_best_odd_result.add(object.getMatchBestOddResult());
                    str_match_best_odd_result = array_match_best_odd_result.toArray(str_match_best_odd_result);
                }

                setAdapterToListView();
            }

In the try section of this code u can see I make a log of the result to see what is coming from the server i just get this : D/resultTT: []

and as you see the try is inside the else section so in the if statement of this section i check if the result is null or empty ; but the code passes it and enter the else statement but still showing that the returned result array is empty.

I want some help to find the reason behind this empty returned array even it loads fine at the start up. why can not it get the information after I choose any element in the spinner and then come back to the default (today) element?

UPDATE : this is my php side-server api code

<?php

    include_once ('includes/variables.php');

    DEFINE ('DB_HOST', $host);
    DEFINE ('DB_USER', $user);   
    DEFINE ('DB_PASSWORD', $pass);
    DEFINE ('DB_NAME', $database);

    $mysqli = @mysql_connect (DB_HOST, DB_USER, DB_PASSWORD) OR die ('Could not connect to MySQL');
    @mysql_select_db (DB_NAME) OR die ('Could not select the database');

 ?>

<?php

    mysql_query("SET NAMES 'utf8'"); 
    $date_offset = mysql_real_escape_string($_GET[d_o]);
    //$date_offset = 0;
    if(empty($date_offset) || $date_offset == "0")
    {
        $date_offset_value = "0";
        $query="SELECT a.*, m.match_id, m.match_time, m.en_tournament_name FROM app_banko a inner join matches_of_comments m on m.match_id = a.match_id where a.date_offset = $date_offset_value limit 20";         
        $resouter = mysql_query($query);
    }
    else
    {
        $date_offset_value = $date_offset;  
        $query="SELECT a.*, m.match_id, m.match_time, m.en_tournament_name FROM app_banko a inner join matches_of_comments m on m.match_id = a.match_id where a.date_offset = $date_offset_value limit 20";         
        $resouter = mysql_query($query);
    }


    $set = array();

    $total_records = mysql_num_rows($resouter);
    if($total_records >= 1){

      while ($link = mysql_fetch_array($resouter, MYSQL_ASSOC)){

        $set['NewsApp'][] = $link;
      }
    }

     echo $val= str_replace('\\/', '/', json_encode($set)); 

?>
Someplace answered 12/4, 2016 at 14:18 Comment(5)
Can not understand why you set spinner.setSelection(4); also your getting response from server like [ ] and its a String format so it return false when you call if (null == result || result.length() == 0) it goes to else statement.Dallas
I use spinner.setselection(4) to call the information of today when the app starts up. and the interesting thing is when i set the spinner to 4 it calls the today information but when I change to another date and come back to today (click today in the spinner again) I just get [] even I get a result with the same call when the app starts upSomeplace
You have Three spinner items right ? why you write case 3 , 4, 5. Does you have any other items in your spinner ?Dallas
I have more items but i just mentioned three here the problematic onesSomeplace
post your doInBackgroundIaniana
M
4

Your result string is an empty array but not an empty string. The empty array is represented as the following string:

String result = "[]";

In that case result.length() is equal to 2.

When parsing JSON you need to know if the parsed object is of type Object or of type Array. The former one is wrapped with braces {}, the later one with square brackets [].

So the following line:

JSONObject mainJson = new JSONObject(result);

Should probably be:

JSONArray mainJson = new JSONArray(result);

But I cannot emphasize enough that you need to know what your API returns if you want to be able to parse it correctly.

EDIT:

Well, json_encode will have a hard time to guess whether it should create a JSON Array or a JSON Object out of the empty array that you created with $set = array();.
Adding objects to the array like you do in your loop makes it obvious for json_encode that it should create a JSON Object.
I don't know if you can force json_encode's behavior, but worst case you could check yourself if the array is empty and return "" or null if the array is empty.

$set = array();

$total_records = mysql_num_rows($resouter);
if ($total_records >= 1) {
  while ($link = mysql_fetch_array($resouter, MYSQL_ASSOC)) {
    $set['NewsApp'][] = $link;
  }
  echo $val= str_replace('\\/', '/', json_encode($set)); 
} else {
  echo $val="";
}
Mlle answered 15/4, 2016 at 6:51 Comment(3)
I updated my question with my server-side so you can check my return typeSomeplace
@BaselShbeb Updated answer.Mlle
Your answer will be useful if I want to check if the array is empty or not in this edit will help my app code to determine if the array is empty or not. But the problem is that the array should not be empty I do not want to check if it is empty or not because i know it should not be empty because I call it in start up and it returns elements. So I do not want to know if it is empty or not I want to know why it returns full result in start up and returns empty result when I click on today element in my spinner (in other words I want to know why it is empty while it should not be).Someplace
A
4

If you get an array in return when expecting an object, there might be something wrong with the request to the API. One way is to figure it out it set up Wireshark on the development machine to sniff and filter the traffic. Then you can see if your request is faulty.

Amaleta answered 15/4, 2016 at 6:58 Comment(1)
I updated my question with my server-side php script I do not think there is something wrong with it because I get response in some cases (today information is being called on start up but same call return empty array when i click on today item in my spinner)Someplace
B
4

It is possible that the value of the response argument from the onPostExecute method contains stringified JSONArray, not JSONObject.

You can always test this with:

try:
    JSONArray jsonArray = new JSONArray(result);
catch(JSONException e) {
    // String `result` is not an array. Parse it as a regular JSONObject.
}

Testing wheter string is an empty json array (depends on it's formatting, especially when it may contain some white characters) checking it's length might be a pretty bad idea.

It all depends how are determined an API endpoints that you are calling.

One more tip at the end. If you are planning to consume REST API I strongly recommend using:

  1. Retrofit - which allows you to easily define interfaces to access your API,
  2. GSON - to automatically convert responses for Java models.
Beora answered 15/4, 2016 at 7:3 Comment(0)
A
4

please put a check result.isEmpty() in your try block condition may this could solve your problem.

Acanthaceous answered 16/4, 2016 at 8:37 Comment(0)
H
4

you can not directly get response in string . it can use JSONObject and JSONArray.

Hymie answered 16/4, 2016 at 10:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.