Search code examples
javascripthtmlmongodbmongodb-atlasmongodb-stitch

MongoDB StitchClient cannot be accessed inside a js function


I have already called stClient.login function inside "addUser()" and "loginUser()" and they worked pretty well. I am able to add the user to my MongoDB database and find the user when login clicked. (dont bother with delete one) After finding a logged user in DB, i am loading a new HTML page where i pass the name of the logged user and profil photo retrieved from MongoDB. Besides, i also want to display the comments of the logged user along with the name and profil photo. Here the issue comes: in showComments method, i am not able to access the stitch Client. Any help is so much appreciated. Below is the code:

Html 1:

<!DOCTYPE html>
<html>
<head>
    <title>myFb</title>
     <link rel="stylesheet" type="text/css" href="style1.css">
    <script src="https://s3.amazonaws.com/stitch-sdks/js/library/v3/stable/stitch.min.js"></script>
    <script src="assig02.js"></script>

</head>
<body onload="onLoadConnectDB()">


<p>Hello My App</p>

<div id="wlcom" align="center">
    <button name="adding" onclick="addUser()">Add User</button><br>
    <button name="deleting" onclick="deleteUser()">Delete User</button> <br>
    <button name="logging" onclick="loginUser()">Login</button><br>
</div>


</body>
</html>

Common JS for 2 HTMLs:

let db;
    let itemsCollection;
    let stClient;
    let globalName;
    let temp;

     let clientPromise = stitch.StitchClientFactory.create('facebookclone-tlwvi');

    function onLoadConnectDB(){
        clientPromise.then(stitchClient=>{
            stClient=stitchClient;
            db = stClient.service('mongodb', 'mongodb-atlas').db('FbUsers');
            itemsCollection=db.collection("ClonedFbUsers");
        });

    }

function addUser(){
    var n= prompt("Your username: ")
    const userId = stClient.authedId();
    stClient.login().then(()=>
        itemsCollection.insertOne({ owner_id: stClient.authedId(), userName : n , profilePhoto: "https://avatarfiles.alphacoders.com/115/115265.png", photos: ["NULL"],comments: [{msg:"NULL",time:"NULL",like:0}] })
        ).then(() => itemsCollection.find({}).execute())
    .then(docs =>
      docs.forEach((doc, index) =>
        console.log(`${index}: ${JSON.stringify(doc)}`)
        )
      );
 // });
    alert("added");
}

function deleteUser(){

    var d= prompt("Username to delete: ");
    const userId = stClient.authedId();
    stClient.login().then(()=>
        itemsCollection.deleteOne({ userName: "Messi" })
        ).then(() => itemsCollection.find({}).execute())
    .then(docs =>
      docs.forEach((doc, index) =>
        console.log(`${index}: ${JSON.stringify(doc)}`)
        )
      );
    alert("User "+d+ " deleted.");


}

function loginUser(){
var n= prompt("Your username: ");
globalName=n;
    const userId = stClient.authedId();
    try{
    stClient.login().then(()=>

         itemsCollection.find({ userName : n }).execute()
        ).then(docs=>

        loadUser(n,docs.map(c=>c.userName),docs.map(c=>c.profilePhoto)) //found result in db, send userName and pp link while loading a new user
        );

}catch(err){
    alert("not found a user");
}

 // });
}
function loadUser(name,usName,pp){
if(usName!=""||usName!=null){
//sending name and profile photo link retrieved form db to 2nd HTML
    document.location = "user.html?name="+encodeURIComponent(usName)+"&prof="+encodeURIComponent(pp);
    //document.getElementById("name").value=name;
}else{
    //no user in db
    alert(name+ " is not found");
}

}
 function onLoad () {
    //onLoadConnectDB();

    var pic;
    var url = document.location.href,
        params = url.split('?')[1].split('&'),
        data = {}, tmp;
    for (var i = 0, l = params.length; i < l; i++) {
         tmp = params[i].split('=');
         data[tmp[0]] = tmp[1];
    }
    document.getElementById('name').value = data.name;
    document.getElementById('pp').src=decodeURIComponent(data.prof);
    showComments(data.name);

   // document.getElementById('pp').value=data.pp;
}

 function showComments(globalName){

//ISSUE IS HERE!!

        stClient.login().then(()=>

         itemsCollection.find({ userName : globalName }).execute()
        ).then(docs=>


        document.getElementById("comments").innerHTML = docs.map(c => "<div>" + c.comments + "</div>").join("")
        );
        };

HTML2

<!DOCTYPE html>
<html>
<head>
    <title>MyProfile</title>
     <link rel="stylesheet" type="text/css" href="style2.css">
     <script src="https://s3.amazonaws.com/stitch-sdks/js/library/v3/stable/stitch.min.js"></script>
     <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js" type="text/javascript"></script>
    <script src="assig02.js"></script>
</head>


  <header>
  <div class="Header">
  <div class="search">
    <img src="white.png" >
</div>
    <div class="profile curs">
    <img src="me+.png">
    <span class="barr" >     &nbsp &nbsp Home </span><span> &nbsp &nbsp &nbsp&nbsp &nbsp &nbsp&nbsp &nbsp &nbsp&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp&nbsp &nbsp &nbsp&nbsp&nbsp &nbsp<img src="frndd.png"> &nbsp <img src="messengerr.png"> <img src="notf.png" style=""> &nbsp &nbsp &nbsp &nbsp <img src="secret.png"></span>
    </div>  
    </div>
    </header> 


<body onload="onLoad()">
<img id = "pp" src="" width="50" height="50">
<p> <input style="border: none; font-size: 20px; width: 100%" id="name" type="text" readonly></p>


<button type="submit" onclick="addPhoto()">Add Photo</button> <br>
<button type="submit">Choose Profile Photo</button><br>

<div class="comments" id="comments" onclick ="showComments()">
Show comments


</div>

</body>
</html>

Solution

  • The issue is relating to async/sync communication. After separating js for html2, i was calling onLoad2() function inside onLoad() function after assuming the connection is established, but no. Should 'wait' till the connection is established and then call another function. js2:

        let db;
        let itemsCollection;
        let stClient;
        let globalName;
        let temp;
    
        let clientPromise = stitch.StitchClientFactory.create('facebookclone-tlwvi');
    
    
    function onLoad(){
    
            clientPromise.then(stitchClient=>{
                stClient=stitchClient;
                db = stClient.service('mongodb', 'mongodb-atlas').db('FbUsers');
                itemsCollection=db.collection("ClonedFbUsers");
                onLoad2(); //if you call outside then, wont work. onLoad2() will be interpreted before establishing connection to db
    
    
            });
        }
    
    
         function onLoad2 () {
        var pic;
        var url = window.location.href,
            params = url.split('?')[1].split('&'),
            data = {}, tmp;
        for (var i = 0, l = params.length; i < l; i++) {
             tmp = params[i].split('=');
             data[tmp[0]] = tmp[1];
        }
        document.getElementById('name').value = data.name;
        document.getElementById('pp').src=decodeURIComponent(data.prof);
        showComments(data.name);
    
    }
    
     function showComments(globalName){
        console.log("i am here");
        const userId = stClient.authedId();
    
            stClient.login().then(()=>
    
             itemsCollection.find({ userName : globalName }).execute()
            ).then(docs=>
    
    
            document.getElementById("comments").innerHTML = docs.map(c => "<div>" + c.comments.msg + "</div>").join(" ")
            );
            }
    
    
       function addComment(){
    
        var n=document.getElementById("name").value;
    
        var com= document.getElementById("comment").value
       stClient.login().then(()=>
            itemsCollection.updateOne({userName : n}, {$push:{comments:{msg:com,time:"22:30",like:4}}})
            ).then(() => itemsCollection.find({}).execute())
        .then(docs =>
          docs.forEach((doc, index) =>
            console.log(`${index}: ${JSON.stringify(doc)}`)
            )
          );
    
       }
    

    HTML for the js2:

        <!DOCTYPE html>
    <html>
    <head>
        <title>MyProfile</title>
         <link rel="stylesheet" type="text/css" href="style2.css">
         <script src="https://s3.amazonaws.com/stitch-sdks/js/library/v3/stable/stitch.min.js"></script>
            <script src="assig022.js"></script>
    </head>
    
    
      <header>
      <div class="Header">
      <div class="search">
        <img src="white.png" >
    </div>
        <div class="profile curs">
        <img src="me+.png">
        <span class="barr" >     &nbsp &nbsp Home </span><span> &nbsp &nbsp &nbsp&nbsp &nbsp &nbsp&nbsp &nbsp &nbsp&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp&nbsp &nbsp &nbsp&nbsp&nbsp &nbsp<img src="frndd.png"> &nbsp <img src="messengerr.png"> <img src="notf.png" style=""> &nbsp &nbsp &nbsp &nbsp <img src="secret.png"></span>
        </div>  
        </div>
        </header> 
    
    
    <body onload="onLoad()">
    <img id = "pp" src="" width="50" height="50">
    <p> <input style="border: none; font-size: 20px; width: 100%" id="name" type="text" readonly></p>
    
    
    <button type="submit" onclick="addPhoto()">Add Photo</button> <br>
    <button type="submit">Choose Profile Photo</button><br>
    
    <div class="comments" id="comments">
    </div>
    <br>
    
    
        <input type="text" name="comment" id="comment" placeholder="Type comment">
        <button onclick="addComment()">Send</button>
    
    </body>
    </html>