Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When posting to my Django API : errorcom.google.gson.JsonParseException: unable to parse json

Can someone tell me what I am doing wrong in this post?

I suspect I am posting to my django API incorrectly. I have basically a Question object that has a field for an array of Answers. I can post correctly without the answers, but when I try to add the JsonArray for answers the post fails with the unable to parse error.

LogCat Excerpt

05-21 00:12:52.875  15720-15720/com.pipit.waffle D/ConnectToBackend﹕ {"text":"gf or ed","answers":[{"text":"gf","votes":0,"id":null},{"text":"ed","votes":0,"id":null}],"user_id":"temp user id"}
05-21 00:12:52.875  15720-15720/com.pipit.waffle D/ConnectToBackend﹕ postQuestion called with {MY API} and has errorcom.google.gson.JsonParseException: unable to parse json
05-21 00:12:52.875  15720-15720/com.pipit.waffle D/ConnectToBackend﹕ postQuestion returns result with NULL

Django Side

serializers.py

class EmbeddedAnswerSerializer(serializers.ModelSerializer):
    votes = serializers.IntegerField(read_only=True)
    picture = serializers.ImageField(read_only=True)
    class Meta:
        model = Answer
        fields = ('id', 'picture', 'text', 'votes',)


class QuestionSerializer(serializers.ModelSerializer):
    answers = EmbeddedAnswerSerializer(many=True, source='answer_set')

    class Meta:
        model = Question
        fields = ('id', 'answers', 'created_at', 'text', 'user_id',)


class AnswerSerializer(serializers.ModelSerializer):
    text = serializers.CharField(read_only=True)
    vote = serializers.BooleanField(required=True)
    picture = serializers.ImageField(read_only=True)
    votes = serializers.IntegerField(read_only=True)

models.py

class Question(models.Model):
    user_id = models.CharField(max_length=36)
    text = models.CharField(max_length=140)
    created_at = models.DateTimeField(auto_now_add=True)

    def __unicode__(self):
        return u'Question #{}'.format(self.pk)

class Answer(models.Model):
    picture = models.ImageField(("Picture"), upload_to=upload_pic_to, blank=True)
    question = models.ForeignKey(Question)
    text = models.CharField(max_length=25)
    votes = models.IntegerField(default=0)

    def __unicode__(self):
        return u'Answer to question {} ({} votes)'.format(self.question_id, self.votes)

Client Side (android)

public static void postQuestion(final Context mcontext, Question mquestion){
        JsonArray answerarray = new JsonArray();
        JsonObject answerjson = new JsonObject();
        JsonObject answerjson2 = new JsonObject();
        answerjson.addProperty("text", mquestion.getChoices().get(0).getAnswerBody());
        answerjson2.addProperty("text", mquestion.getChoices().get(1).getAnswerBody());
        answerjson.addProperty("votes", 0);
        answerjson2.addProperty("votes", 0);
        answerjson.addProperty("id", mquestion.getId());
        answerjson2.addProperty("id", mquestion.getId());
        answerarray.add(answerjson);
        answerarray.add(answerjson2);

        JsonObject json = new JsonObject();
        json.addProperty("text", mquestion.getQuestionBody());
        json.add("answers", answerarray);
        json.addProperty("user_id", "temp user id");
        final String url = "my endpoint";
        Ion.with(mcontext) //Ion Koush is just a library for making async android requests to a URL  - doubt this is the problem
                .load(url)
                .setJsonObjectBody(json)
                .asJsonObject()
                .setCallback(new FutureCallback<JsonObject>() {
                    @Override
                    public void onCompleted(Exception e, JsonObject result) {
                        if (e != null){
                            Log.d("ConnectToBackend", "postQuestion called with "+url+" and has error" + e.toString());
                            if (result==null){
                                Log.d("ConnectToBackend", "postQuestion returns result with NULL");
                            }
                        }
                        else{
                            //Do Stuff
                        }

                    }
                });
    }

This is an example of what a successful GET to the same endpoint looks like

{"id":5,"answers":[{"id":10,"picture":"someurl","text":"microsoft","votes":0},{"id":9,"picture":"someurl","text":"apple","votes":0}],"created_at":"2015-03-15T04:14:00.782903Z","text":"MicroSoft or Apple","user_id":"8"}
like image 531
Eric S. Avatar asked May 21 '15 21:05

Eric S.


2 Answers

Are you sure it's not actually a string that is successful rather than a dictionary? I've ran into this problem on the Django side, don't know much about Android.

With python it would be:

import json
your_dict = {...}

# this stringifies the dict
json.dumps(your_dict)

I know you're doing this on the client, so the code above won't be your answer, but it's an idea and hopefully it helps!

like image 158
awwester Avatar answered Sep 17 '22 19:09

awwester


You can try this in an alternative way by changing the QuestionSerializer:

class QuestionSerializer(serializers.ModelSerializer):
    answers = serializers.SerializerMethodField()

    class Meta:
        model = Question
        fields = ('id', 'answers', 'created_at', 'text', 'user_id',)

    def get_answers(self,obj):
        ans_set = AnswerSerializer(Answer.objects.filter(question=obj),many=True)
        return ans_set
like image 21
Prateek099 Avatar answered Sep 19 '22 19:09

Prateek099