0

Hi I am trying to add a new item to my chat, I use RXJava2, to make call to my REST API to get the chat data, with this nested json response.

But I get an NullPointer when I try to add a new item to the Arraylist (Send new message):

09-08 13:35:14.529 2869-2869/com.jonathan.myapp E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.jonathan.myapp, PID: 2869
    java.lang.NullPointerException: Attempt to invoke virtual method 'void com.jonathan.myapp.models.ChatMessageUser.setUserId(java.lang.String)' on a null object reference
        at com.jonathan.myapp.ui.activity.UserChatActivity.attemptSend(UserChatActivity.java:368)
        at com.jonathan.myapp.ui.activity.UserChatActivity.access$000(UserChatActivity.java:56)
        at com.jonathan.myapp.ui.activity.UserChatActivity$3.onClick(UserChatActivity.java:161)

enter image description here

The code I use for sending the message is:

private ArrayList<ChatMessages> messageArrayList;

private void attemptSend() {
    if (TextUtils.isEmpty(message)) {
        mInputMessageView.requestFocus();
        return;
    }

    mInputMessageView.setText("");

    String userid = "1";

    ChatMessages add = new ChatMessages();
    add.setMessage(message);
    add.setCreatedAt(1536407395);
    add.getUser().setUserId(userid);

    messageArrayList.add(add);

    mAdapter.notifyDataSetChanged();
    if (mAdapter.getItemCount() > 1) {
        // scrolling to bottom of the recycler view
        recyclerView.getLayoutManager().smoothScrollToPosition(recyclerView, null, mAdapter.getItemCount() - 1);
    }
}

The Nested JSON:

{
    "error": false,
    "messages": [
        {
            "message": "hej ",
            "message_id": 15,
            "created_at": 1509383626,
            "readedAt": 1536331345,
            "user": {
                "user_id": 2,
                "username": "Lasse",
                "userprofilepicture": "https://static.pexels.com/photos/305239/pexels-photo-305239.jpeg"
            }
        },
        {
            "message": "hej  kar",
            "message_id": 24,
            "created_at": 1510411308,
            "readedAt": 1511165097,
            "user": {
                "user_id": 1,
                "username": "Jonathan",
                "userprofilepicture": "https://d2lm6fxwu08ot6.cloudfront.net/img-thumbs/960w/7YWI2KZZ6N.jpg"
            }
        }
    ],
    "chat_room": {
        "roomId": 1,
        "displayName": "Jonathan",
        "displayNameImage": "https://d2lm6fxwu08ot6.cloudfront.net/img-thumbs/960w/7YWI2KZZ6N.jpg",
        "createdDate": "1532032759"
    }
}

My ChatThreadAdapter:

public class ChatRoomThreadAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    private String userId;
    private int SELF = 100;
    private static String today;

    private Context mContext;
    private ArrayList<ChatMessages> messageArrayList;

    public List<ChatMessages> getChatMessages(){
        return messageArrayList;
    }

    public class ViewHolder extends RecyclerView.ViewHolder {
        TextView message, timestamp, readedstatus;
        ImageView profileimage;

        public ViewHolder(View view) {
            super(view);
            message = (TextView) itemView.findViewById(R.id.message);
            timestamp = (TextView) itemView.findViewById(R.id.timestamp);
            readedstatus = (TextView) itemView.findViewById(R.id.readedstatus);
            profileimage = (ImageView) itemView.findViewById(R.id.avater_image);
        }
    }

    public ChatRoomThreadAdapter(Context mContext, ArrayList<ChatMessages> messageArrayList, String userId) {
        this.mContext = mContext;
        this.messageArrayList = messageArrayList;
        this.userId = userId;

        Calendar calendar = Calendar.getInstance();
        today = String.valueOf(calendar.get(Calendar.DAY_OF_MONTH));
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View itemView;
        if (viewType == SELF) {
            itemView = LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.list_item_message_right, parent, false);
        } else {
            itemView = LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.list_item_message_left, parent, false);
        }
        return new ViewHolder(itemView);
    }

    @Override
    public int getItemViewType(int position) {
        ChatMessages message = messageArrayList.get(position);
        if (message.getUser().getUserId().equals(userId)) {
            return SELF;
        }
        return position;
    }

    @Override
    public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) {
        ChatMessages message = messageArrayList.get(position);

        String timestamp = TextUtils.getDateTimeStampWithTime(message.getCreatedAt());
        String fimage = message.getUser().getUserprofilepicture();
        String readedat = TextUtils.getDateTimeStampWithTime(message.getReadedAt());

        if (message.getUser().getUserId().equals(userId)) {
            // Self
            ((ViewHolder) holder).message.setText(Html.fromHtml(message.getMessage()));

            if (message.getUser().getUsername() != null)
                ((ViewHolder) holder).timestamp.setText(timestamp);

            ((ViewHolder) holder).readedstatus.setVisibility(View.GONE);
            ((ViewHolder) holder).readedstatus.setVisibility(View.GONE);


        } else {
            // Other
            ((ViewHolder) holder).message.setText(Html.fromHtml(message.getMessage()));

            if (message.getUser().getUsername() != null)
                ((ViewHolder) holder).timestamp.setText(timestamp);

            if (fimage.isEmpty()) {
                Picasso.with(mContext).load(R.drawable.ic_no_user)
                        .resize(80, 80)
                        .into(((ViewHolder) holder).profileimage);
            } else {
                Picasso.with(mContext).load(fimage)
                        .resize(80, 80)
                        .into(((ViewHolder) holder).profileimage);
            }
            if (message.getReadedAt().toString().equals("0")){
                ((ViewHolder) holder).readedstatus.setText(mContext.getResources().getString(R.string.message_delivered));
            } else {
                ((ViewHolder) holder).readedstatus.setText(mContext.getResources().getString(R.string.message_readed_at) + " " + readedat);
            }
        }
    }

    @Override
    public int getItemCount() {
        return messageArrayList.size();
    }
}

And my models:

public class ChatMessages {
    @SerializedName("message")
    @Expose
    private String message;
    @SerializedName("message_id")
    @Expose
    private Integer messageId;
    @SerializedName("created_at")
    @Expose
    private Integer createdAt;
    @SerializedName("readedAt")
    @Expose
    private Integer readedAt;
    @SerializedName("user")
    @Expose
    private ChatMessageUser user;

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public Integer getMessageId() {
        return messageId;
    }

    public void setMessageId(Integer messageId) {
        this.messageId = messageId;
    }

    public Integer getCreatedAt() {
        return createdAt;
    }

    public void setCreatedAt(Integer createdAt) {
        this.createdAt = createdAt;
    }

    public Integer getReadedAt() {
        return readedAt;
    }

    public void setReadedAt(Integer readedAt) {
        this.readedAt = readedAt;
    }

    public ChatMessageUser getUser() {
        return user;
    }

    public void setUser(ChatMessageUser user) {
        this.user = user;
    }
}

And the ChatMessageUser model:

public class ChatMessageUser {
    @SerializedName("user_id")
    @Expose
    private String userId;
    @SerializedName("username")
    @Expose
    private String username;
    @SerializedName("userprofilepicture")
    @Expose
    private String userprofilepicture;

    public String getUserId() {
        return userId;
    }

    public void setUserId(String userId) {
        this.userId = userId;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getUserprofilepicture() {
        return userprofilepicture;
    }

    public void setUserprofilepicture(String userprofilepicture) {
        this.userprofilepicture = userprofilepicture;
    }
}
Rahul Chokshi
  • 670
  • 4
  • 18
JonathanNet
  • 1,637
  • 3
  • 15
  • 17

2 Answers2

0

I think you need to initialized private ArrayList messageArrayList; you need to create new ArrayList before adding contain on this list

0

When you instantiate ChatMessages object the user field in that object is null. you must call setUser(ChatMessageUser user) method and pass an existing user object to it before calling add.getUser().setUserId(userid).

Alireza
  • 183
  • 1
  • 10
  • Now I tried with this, but now I dont get any errors, but It dont insert the item: `ChatMessages add = new ChatMessages(); add.setMessage(message); add.setCreatedAt(1536407395); ChatMessageUser user = new ChatMessageUser(); user.setUserId(userid); add.setUser(user); messageArrayList.add(add);` – JonathanNet Sep 08 '18 at 19:10
  • swap lines : user.setUserId(userid); add.setUser(user); – Alireza Sep 09 '18 at 10:02
  • You must setting user object before calling any method of its object – Alireza Sep 09 '18 at 10:04