2

I am fetching a json response from my django response by this url /inbox/<str:username> to get a json response of all the messages in the conversation with that user. The problem starts with the inbox page which holds the threads and chatbox on the same page like instagram which looks like this Chat Inbox

but as it can be seen that I want the url to be like with the username. Let's say when I click on thread with dummy I want the url to be like "inbox/dummy" but in this my url is "/inbox" which will not let me initiate the socket for messaging, my views.py that renders this inbox template is

views for inbox

thread_objs= Thread.objects.by_user(user=request.user)
    l=len(thread_objs)
    chat_objs=[]
    for i in range(l):
        chat_objs.append(list(thread_objs[i].chatmessage_set.all()).pop())

    
    chat_objs_serialized=[]
    for i in range(l):
        chat_objs_serialized.append(json.dumps(ChatMessageSerializer(chat_objs[i]).data))
    for i in range(l):
        print(chat_objs_serialized[i])
    
    thread_objs_list=[]
    
    for i in range(l):
        thread_objs_list.append(json.dumps(ThreadSerializer(thread_objs[i]).data))
    
    return render(request,'uno_startup/inbox.html',context={"Threads":thread_objs_list,"Messages":chat_objs_serialized})

now when I click a thread it's content should load on the right side of screen as with the javascript of inbox.html that is this page in this image.

javascript of inbox

<body>
<div class='container'>
    <div class='row'>
        <div class="col-md-4" id ="Threadholder">
            <ul id ="Threadbox">
            {% for object in threads %}
                <li><a href=" ">{% if user != object.first %}{{ object.first }}{% else %}{{ object.second }}{% endif %}</a></li>
            {% endfor %}
            </ul>

        </div>    
    
        <div class="col-md-8" id="Chatholder" >
            <ul id="Chatbox">

            </ul>
     
            
         <form id="form" method="POST">
                 <input type="hidden" value="{{ user.username }}" id="myusername">
                 <input type="text" id="chat_message">
                 <input type="submit" class="btn btn-primary">
         </form>
            
        </div>
    </div>
</div>
<script>
    var threads={{ Threads|safe }};
    var messages={{ Messages|safe }};
    const l=threads.length
    const threadholder=$("#Threadbox")
    for(i=0;i<l;i++){
        var data=JSON.parse(threads[i])
        var Message=JSON.parse(messages[i])
        var username =data.second.username
        if (username=="{{ user.username }}"){
            username=data.first.username
        }
        
        var thread=document.createElement("li")
        var main=document.createElement("a")
        
        var div=document.createElement("div")
        var username_holder=document.createElement("p")
        div.className="thread"
        
        var p=document.createElement("p")
        
        p.innerText=Message.message
        
        username_holder.innerText=username
        div.appendChild(username_holder)
        div.appendChild(p)
        main.appendChild(div)
        thread.appendChild(main)
        threadholder.append(thread)
        
    };
function add_message(message){
            
            message=JSON.parse(message)
            const chatholder=$("#Chatbox")
            
            console.log(message.user.username)
            const chat_message= document.createElement("li")
            var div= document.createElement("div")
            var p = document.createElement("p")
            var sender=message.user.username
            var text=message.message
            p.innerText=text
            div.appendChild(p)
            chat_message.appendChild(div)
            if(sender=="{{ user.username }}"){
                chat_message.className="user"
            }
            else{
                chat_message.className="other"
            }
            chatholder.prepend(chat_message)
            
        }
        $(document).ready(function(){
        $("li").click(function(){
            $("#Chatbox").empty()
        
            
            var other_user= this.children[0].children[0].children[0].innerText

            fetch(`/inbox/${other_user}`).then(response => response.json())
                .then(data => data.messages.reverse().forEach(add_message)) 
                
                
          })
        
        })

and this is the function that returns the json response

view for json response

thread=Thread.objects.get_or_new(user=request.user,other_username=username)
    messages=thread[0].chatmessage_set.all()
    l= len(messages)

    messages_serialized=[]
    for i in range(l):
        messages_serialized.append(json.dumps(ChatMessageSerializer(messages[i]).data))
    print(messages)
    return JsonResponse({"messages":messages_serialized})

and this Chat function is called via this url /inbox/<str:username> I want a method that can help me get the thread open without reloading, and updates the url, I have used AJAX but it didn't help as it also took to me the page where it gave me the Json Response from django, changing the original page.

The failed AJAX implementation

<script>
    var threads={{ Threads|safe }};
    var messages={{ Messages|safe }};
    const l=threads.length
    const threadholder=$("#Threadbox")
    for(i=0;i<l;i++){
        var data=JSON.parse(threads[i])
        var Message=JSON.parse(messages[i])
        var username =data.second.username
        if (username=="{{ user.username }}"){
            username=data.first.username
        }
        
        var thread=document.createElement("li")
        var main=document.createElement("a")
        
        var div=document.createElement("div")
        var username_holder=document.createElement("p")
        div.className="thread"
        
        var p=document.createElement("p")
        
        p.innerText=Message.message
        
        username_holder.innerText=username
        div.appendChild(username_holder)
        div.appendChild(p)
        main.appendChild(div)
        thread.appendChild(main)
        threadholder.append(thread)
        
    };
function add_message(message){
            
            message=JSON.parse(message)
            const chatholder=$("#Chatbox")
            
            console.log(message.user.username)
            const chat_message= document.createElement("li")
            var div= document.createElement("div")
            var p = document.createElement("p")
            var sender=message.user.username
            var text=message.message
            p.innerText=text
            div.appendChild(p)
            chat_message.appendChild(div)
            if(sender=="{{ user.username }}"){
                chat_message.className="user"
            }
            else{
                chat_message.className="other"
            }
            chatholder.prepend(chat_message)
            
        }
        $(document).ready(function(){
        $("li").click(function(){
            $("#Chatbox").empty()
        
            
            var other_user= this.children[0].children[0].children[0].innerText
            <script>
    var threads={{ Threads|safe }};
    var messages={{ Messages|safe }};
    const l=threads.length
    const threadholder=$("#Threadbox")
    for(i=0;i<l;i++){
        var data=JSON.parse(threads[i])
        var Message=JSON.parse(messages[i])
        var username =data.second.username
        if (username=="{{ user.username }}"){
            username=data.first.username
        }
        
        var thread=document.createElement("li")
        var main=document.createElement("a")
        
        var div=document.createElement("div")
        var username_holder=document.createElement("p")
        div.className="thread"
        
        var p=document.createElement("p")
        
        p.innerText=Message.message
        
        username_holder.innerText=username
        div.appendChild(username_holder)
        div.appendChild(p)
        main.appendChild(div)
        thread.appendChild(main)
        threadholder.append(thread)
        
    };
function add_message(message){
            
            message=JSON.parse(message)
            const chatholder=$("#Chatbox")
            
            console.log(message.user.username)
            const chat_message= document.createElement("li")
            var div= document.createElement("div")
            var p = document.createElement("p")
            var sender=message.user.username
            var text=message.message
            p.innerText=text
            div.appendChild(p)
            chat_message.appendChild(div)
            if(sender=="{{ user.username }}"){
                chat_message.className="user"
            }
            else{
                chat_message.className="other"
            }
            chatholder.prepend(chat_message)
            
        }
        $(document).ready(function(){
        $("li").click(function(){
            $("#Chatbox").empty()
        
            
            var other_user= this.children[0].children[0].children[0].innerText

           $.ajax({
            type: "GET",
            url: {% url 'Chat' username=other_user %}, 
            data: {'Messages': messages}
        })
        .done(function(response) {
            console.log(reposne)
        });
                
          })
        
        })
                         
                
          })
        
        })
Syed Bilal Ali
  • 124
  • 1
  • 10
  • “I have used AJAX but it didn't help as it also took to me the page”—it sounds like the AJAX implementation was faulty then. AJAX by definition shouldn't be redirecting the page. Perhaps you'd want to share how you tried that part? I can't think of a solution to your problem that doesn't involve JavaScript. – DJ Ramones Sep 29 '20 at 05:06
  • I have added it with the heading Failed ajax implementation, you can check now – Syed Bilal Ali Sep 29 '20 at 05:11
  • I realize the AJAX issue might be with the Django view after all. I'm writing an answer. – DJ Ramones Sep 29 '20 at 05:24

1 Answers1

2

Your Django view is reloading the page because it's returning a response of content type HTML instead of, say, JSON.

Instead of

return render(request,'uno_startup/inbox.html',context={"Threads":thread_objs_list,"Messages":chat_objs_serialized})

Do something like

from django.http import JsonResponse
...
return JsonResponse({"Threads": thread_objs_list, "Messages": chat_objs_serialized})

You should still fetch this response from the front-end using JavaScript/AJAX.

As for how to change the URL without inducing a page refresh, refer to this answer.

DJ Ramones
  • 823
  • 1
  • 5
  • 11