0

Doing a JS exercise: I know it has to be pretty darn simple, but I just can't figure it out. I have created a table from a JSON file, managed to create a table with the elements they required. Now I have to add the link from the field "url" on the file, to the "first_name" element from the table. I know i have to use the href"" and I guess i have to create a function to identify just the "first_name" and add the link.

This is the VAR Data created with the JSON file, at the top of my JS file

var data = {
   "status":"OK",
   "copyright":" Copyright (c) 2019 Pro Publica Inc. All Rights Reserved.",
   "results":[
      {
         "congress": "113",
         "chamber": "Senate",       
         "num_results": 105,
         "offset": 0,
         "members": [
              {
                 "id": "A000360",
                 "title": "Senator, 2nd Class",
                 
                 "first_name": "Lamar",
                 "party": "R",
                 "twitter_account": "SenAlexander",
                 "seniority": "11",
                 "phone": null,
                 "fax": null,
"url": "https://www.alexander.senate.gov/public",
                 "state": "TN",
             
                           {
                 "id": "A000368",
                 "title": "Senator, 3rd Class",
                 "first_name": "Kelly",
                 "party": "R",

//...the list goes on

And this is the funcition made to create the table with some elements from the Variable :

function createTable(tbody, data, field) {  
  for (var i = 0; i < data.length; i++) {
    var row = document.createElement("tr");
    tbody.appendChild(row);
    
    for (var j = 0; j < field.length; j++) {
      var cell = document.createElement("td");
    var texto = document.createTextNode(data[i][field[j]])
      row.appendChild(cell);
      cell.appendChild(texto)
    }
  }
}

createTable(
  document.getElementById("senate-data"), data.results[0].members, 
  ["first_name", "party", "state", "seniority", "votes_with_party_pct"]
);
What I would like to find a way , according to my level (a total begginer), of adding those urls from the "url" to the "first_name" field in the list.

Or at least give me an example so I can work with it.

notADevYet
  • 307
  • 2
  • 13
  • So do you mean that you want the result to output something like Lamar ? – Doug F May 06 '19 at 12:31
  • I think so, To transform the column with "First_name" into links , with the links provided in the 'url' elements from the Variable Data. Sorry if i was not clear enough, still learning how to word it – notADevYet May 06 '19 at 12:38
  • any lead? maybe buy creating a var linksForNames = document.getElementById("url"); and then do something with it? – notADevYet May 06 '19 at 13:12

1 Answers1

0

As there is no CreateHtmlNode available, you will need to use .innerHTML instead.

I altered your function, adding an additional parameter expecting an object with the fields "linkField" (target holding the link) and "urlField" (Hyperlink field in the JSON response):

function createTableWithLink(tbody, data, field, urlInfo) {
  var texto;

  for (var i = 0; i < data.length; i++) {
    var row = document.createElement("tr");
    tbody.appendChild(row);

    for (var j = 0; j < field.length; j++) {
      var cell = document.createElement("td");
      if (field[j] === urlInfo.linkField) {
        cell.innerHTML = '<a href="' + data[i][urlInfo.urlField] + '">' +
          data[i][field[j]] + '</a>';

      } else {
        cell.innerHTML = data[i][field[j]];
      }
      row.appendChild(cell);
    }
  }
}

createTableWithLink(
  document.getElementById("senate-data"), data.results[0].members, 
  ["first_name", "party", "state", "seniority", "votes_with_party_pct"], 
  {
    linkField: "first_name",
    urlField: "url"
  }
);

Here is a Fiddle showing the change.

General note:

As you are a beginner, I hope you don't mind words of advise. I would recommend to stick to ending your lines with a semi-colon, even if it's not required. Also take care of the indentation of your lines as this will help both you and your team members to get into the code more quickly. Well structured code is beautiful :-)

Answers to your questions in comments:

1.) Additional object as parameter:

In Javascript Objects are contained in {} and contain field and values in the form of fieldName: "value" (or "fieldName": "value" as it is required in JSON). Objects can be structured very freely and can contain other Objects, arrays or simple arrays. Here's a bit of reading showing different ways to initialize objects.

There is way more to tell about Objects but that should be it for the beginning.

I personally like to define groups of varriables inside objects as this allows me to access the variables contained via its given names, e.g. as urlInfo.linkField in the createTableWithLink() method. If I had used an array instead, this would have been something like urlInfo[0] instead in case I had used a numeric key array.

2.) Using var linkField = getElementById("first_name") instead:

First of all: getElementById(ELEMENT) will simply return the object with the given ID from the current HTML document so in our case where we are working with a JSON structure containing all the data it would simply not fit.

In case you would have a button that loads the JSON, then you could define two input fields for the URL and link column in the JSON response dynamically and add these as parameters:

<label>Link to be added to: <input type="text" id="link_field" value="first_name"/></label>
<label>Field should be linked to: <input type="text" id="url_field" value="url"/></label>
<input type="button" onclick="createTableOnButtonClick()" value="Create table"/>
// call the original function, pass in the values from the input fields:
function createTableOnButtonClick() {
    createTableWithLink(
      document.getElementById("senate-data"), data.results[0].members, 
      ["first_name", "party", "state", "seniority", "votes_with_party_pct"], 
      {
        linkField: document.getElementById("link_field").value,
        urlField: document.getElementById("url_field").value
      }
    );
}

If you don't require any dynamic definition of the fields, you can always hard-code values and checks inside your function but I would advise against it as you also pass in the fields dynamically. Just for completeness this would be a version of the function with hard-coded checks:

// the URL definition parameter has been reduced as they are now hard-coded
function createTableWithLink(tbody, data, field) {
  var texto;

  for (var i = 0; i < data.length; i++) {
    var row = document.createElement("tr");
    tbody.appendChild(row);

    for (var j = 0; j < field.length; j++) {
      var cell = document.createElement("td");
      // hard-coded checking for field "first_name"
      if (field[j] === "first_name") {
        cell.innerHTML = '<a href="' + data[i]["url"] + '">' +
          data[i]["first_name"] + '</a>';

      ...

3.) When to use square brackets ([]) or dot-syntax (.property)?

Arrays are a special type of object so you may access arrays as well with "Property accessors".

Here is a very good Stack Overflow Q&A about accessing objects and arrays using different notations.

Basically you can always use the property accessor if you have a key in the form of a string but you can always use array accessors independent of the index type:

var numArr= [20, "Test"];
var stringArray= [];
stringArray["testValue"]= "4711";
stringArray["anotherValue"]= "0815";

console.log(numArr[0]);
console.log(stringArray.testValue);
console.log(stringArray["anotherValue"]);

// won't work:
console.log(numArr.0);
SaschaM78
  • 4,376
  • 4
  • 33
  • 42
  • I works! thanks! The only problem is that I dont think I understand enough what you did to explain it with my own words, or to replicate it :/ . For the words of advise, are always very appreciated. I am just on my first days with this, and words of advise are golden. Just two questions 2 see if i can understand it beeter : {} at the end, defining variables linkField and urlField ... Why putting them there? could I define them inside the function?like "var linkField = getElementbyId("first_name")? or that is wrong? Is just that the way I call the function is getting too complicated – notADevYet May 06 '19 at 14:03
  • and last but not least ... The proper use of when to use [] ( like in cell.innerHTML = '' + data[i][field[j]] + '' ) , have me spinning...any good resource to clarify that use – notADevYet May 06 '19 at 14:11
  • @notADevYet I'll try to answer your comments as part of an edit to my answer as there is more room :-). I will add another comment to notify you as soon as they are answered. – SaschaM78 May 06 '19 at 14:12
  • no rush! just whenever you have some spare time. You have done more than enoguh though . – notADevYet May 06 '19 at 14:23
  • @notADevYet I added some explanations and examples to the answer. Hope that makes things clearer? P.S. I don't know if you can change your user name from "notADevYet" to "ADevNow" in the future ;-) – SaschaM78 May 06 '19 at 14:58
  • It helps quite a lot! I have still a lot to look into ... do you mean that you are not confident I could become a Dev??? hahahaha...i must say that, at this point, neither do I ... but I gotta say that the patience an attitude I have found from guys like you in this community in my short time around, is really great. By now lets say I might change it for ADevInaDistantFuture – notADevYet May 07 '19 at 07:47
  • @notADevYet no, absolutely not! I meant that at some point in time your name will no longer fit ;-). Great that helped, hope we'll read us in the future again! Happy learning! – SaschaM78 May 07 '19 at 07:51