0

I have been tasked with using my skills with HTML/CSS/JavaScript/jQuery to solve a block of code according to these requirements:

Requirements: - Use ajax via the add_user function to submit the user entered data.
- You can assume the service will respond with 200 status.
- Display an error in red at the top of the form when the add user service responds with success property with a value of false. Use the error property as the message.
- Display new users in the users list when the response returns a success property
- Highlight the email input when a user enters an invalid email address. Also, display the text "please enter a valid email address" in red.
NOTE: The service will not provide this validation functionality, and will accept invalid emails.

//example usage.
addUser('john', 'smith', function(response){
    console.log('response is: ' + JSON.stringify(response)); 
});

/*
################################### DO NOT MODIFY BELOW THIS LINE ##########
############################################################################
*/
// Add user service wrapper.
function addUser(username, email, callback) {
    var response;

    if(username === "Error"){
        response = JSON.stringify({
            success: false,
            error: "Error is not acceptable username."
        });
    } else {
        response = JSON.stringify({
            success: true,
            user: {
                username: username,
                email: email
            }
        });   
    }

    $.ajax({
        url: '/echo/json/',
        type: "post",
        data: {
            json: response
        },
        success: callback
    });
};

The following HTML applies:

<h2>Add a User:</h2>
<form>
    <input type="text" name="username" placeholder="name">
    <input type="email" name="email" placeholder="email">
    <button>add user</button>
</form>
<h2>Users:</h2>
<ul id="users"></ul>

CSS:

body {
    font-family: Helvetica, Sans, Arial;
}
p, ul {
    padding: 10px;
}
ul {
    margin: 5px;
    border: 2px dashed #999;
}

OK, hopefully you're still with me. I have a strong understanding of Object-Oriented JavaScript, as well as jQuery, HTML, and CSS. However, I have very little experience with AJAX, and none with JSON syntax/application. Therefore, some aspects of this project seem very straightforward to me, and I do not believe I need assistance in figuring them out. The things I already know how to do properly include:

  • Displaying an error in red above the form (retrieving the error information is a different story)
  • Displaying new users in the unordered list section
  • Highlight the email input when an invalid email address is entered (using client-side validation)

The issues I am having in understanding this project focus on submitting and retrieving the data that is entered in the form. It appears as though the function addUser() first defines the variable response with a 'String' data type version of an 'Object' that contains key:value pairs of 'success: boolean, error: string' or 'success: boolean, user: {username:string,email:string}' - Here is where I run into my first area of trouble...

If the objects containing those key:value pairs are to be relied on for determining whether or not an error has occurred during validation, and to retrieve data such as error messages and strings associated with the username and email, it would make sense to keep them as actual objects, rather than 'stringified' objects. As strings, I do not know how to access the value of a property of that object. If they were objects, I could simply refer to them using dot notation and retrieve their properties' values. (i.e. sampleObj.success or sampleObj.error) It seems as though JavaScript functions such as eval() and JSON.parse() would suffice to return these strings into proper objects, but I have no idea how to implement those functions properly.

The second major issues I am experiencing relates to the jQuery call of the .ajax() method. I have a very rudimentary understanding of how AJAX operates, but the syntax used here confuses me. I understand that the data: {json:response} is being sent to the url:'/echo/json/' using the type:'post', but I do not understand how that data can be retrieved after this has taken place. I also do not understand what the value of 'response' is referring to in that process.

Finally, I do not understand the use of a callback function at the end of the $.ajax() statement, and how it relates to the initial call of the addUser() function as a result of clicking the form button input. I do not understand its purpose, or how it would be used syntactically.

I understand this is a fairly complicated project, and I may be asking a lot. But I have spent many hours over several days trying to make sense of this using my own knowledge and existing online resources, but have not gotten very far despite my diligence. I hope someone can assist me in understanding this example.

A link to a live version of this project (jsfiddle.net)

//EDIT// An updated link to the jsfiddle workflow, with correct jQuery selectors and additional functionality for displaying error messages / user input: http://jsfiddle.net/brianjsullivan/5vv5w/

Brian S
  • 121
  • 2
  • 15
  • You may want to see [This](http://stackoverflow.com/questions/425095/submit-form-using-ajax-and-jquery) as well as [This](http://stackoverflow.com/questions/12715994/how-do-i-submit-form-data-using-jquery-ajax). – Gurminder Singh Sep 25 '13 at 18:27

3 Answers3

0

The problem is that you forget the # (id) in your code:

JSFIDDLE

$(document).ready(function(){
    $('#button').click(function(){
        $userInput = $('#username').val();
        $emailInput = $('#email').val();

        addUser($userInput,$emailInput,function(response){
            $('#users').html(JSON.stringify(response));
        });
    });    
});
Black Sheep
  • 6,604
  • 7
  • 30
  • 51
  • Absolutely, I had previously used core JS to work on this project, only recently implementing jQuery, and I forgot that particular syntax quirk. Thank you for pointing that out, it's refreshing to see some progress! – Brian S Sep 25 '13 at 18:44
0

Change your code to

$(document).ready(function(){
 $('#button').click(function(){
    $userInput = $('#username').val();
    $emailInput = $('#email').val();

    addUser($userInput,$emailInput,function(response){
        $('#users').html(JSON.stringify(response));
    });
 });
});

Here is Fiddle.

Gurminder Singh
  • 1,755
  • 16
  • 19
  • Your fiddle don`t work...you forget the `#` (id) in `username` and `email` – Black Sheep Sep 25 '13 at 18:44
  • Thanks, I forgot to indicate that I was creating a jQuery object based on the IDs of those HTML elements by using a '#' notation. – Brian S Sep 25 '13 at 18:45
  • Something I can't quite wrap my head around relates to the callback function provided in that addUser() call. If 'response' is a variable that isn't even declared until addUser() begins to run, how is it possible that it can be sent as an argument in this case? I'm failing to see where the variable 'response' takes on any meaning in the progression of this code. – Brian S Sep 25 '13 at 18:47
  • In JQuery ajax, there is a _success_ callback which handles the _response_ form the server e.g. _success: function(responseData){}_.In your case, you can notice that in the AJAX method there is a code snippet **success: callback**, where callback is a function with _response_ as a parameter that have been provided to _addUser_ by you.So, whenever AJAX returns a successful response from the server, this callback function will be executed.Does that make sense? – Gurminder Singh Sep 26 '13 at 05:51
0

The JSON/string issue is a matter of a little experimentation/familiarity with JSON and JSON objects, but requires tons of explanation in lieu of a little testing, so I will focus on parts 2 and 3 of your question. Perhaps someone else is better able than I to address the first part.

An AJAX code block (1) Defines some variables with values, (2) Transmits them to a server-side script for processing, (3) Receives a response from the server.

The "old" construction (we now use the Promises interface) is the easiest way to envision how AJAX works:

$.ajax({
    type: "POST",
    url:  "pagename.php",
    data: "varName=" +varValue+ "&nextVarName=" + nextVarValue,
    success: function(returned_data) {
        //Var returned_data is ONLY available inside this fn!
        alert("Server said: " + returned_data);
    }
});

On the server side (using PHP for this example):

<?php

    $one = $_POST['varName'];  //$one contains varValue
    $two = $_POST['nextVarName'];  //$one contains nextVarValue

    //Do something with the received data, for eg a MySQL lookup

    $result = mysql_result(mysql_query(some lookup),0);

    $out = '<h1>Server says:</h1>';
    $out .='<p>For the purpose of this test, the server sends back:</p>';
    $out .= $result;

    echo $out;  //NOTE: uses echo, not return

Whatever the server side sends to the browser is received as the contents of the variable we have named returned_data.

Note that we must deal with that variable ONLY inside the success function. If we need access to it later on, we can either save the contents into global vars, or inject the data into a hidden DOM element, or ...

These days, though, you want to use the promises interface -- which essentially does the same stuff, but not as clear for the purpose of explanation in an SO post. See below:

Sources:

Kevin Chisholm on jQuery Promise Interface
jQuery 4 U
Daniel Demmel on Promises
José F. Romaniello

cssyphus
  • 37,875
  • 18
  • 96
  • 111
  • Thanks for such a detailed explanation of this process! I am still reviewing the information you presented, as I still do not grasp the concept entirely, but this is a huge step forward in my understanding. For your reference, here is a link to the updated jsfiddle of my work on the project. With the your help and that of others, I was able to formulate a solution to the project that meets all the requirements. [Here is the link](http://jsfiddle.net/brianjsullivan/5vv5w/) – Brian S Sep 25 '13 at 20:09