Peter
Peter

Reputation: 79

Kimono: Function to modify data, explode string and add new a new property

I'm using Kimono to extract some data and create an API:

{
  "name": "site update",
  "count": 4,
  "frequency": "Manual Crawl",
  "version": 1,
  "newdata": true,
  "lastrunstatus": "success",
  "thisversionstatus": "success",
  "thisversionrun": "Sun Feb 07 2016 05:13:26 GMT+0000 (UTC)",
  "results": {
    "collection1": [
      {
        "title": {
          "href": "http://www.tvtrailers.com/scenes/view/id/9418/title-1/",
          "text": "Title 1"
        },
        "pubDate": "February 6, 2016",
        "index": 1,
        "url": "http://www.tvtrailers.com/home/"
      },
      {
        "title": {
          "href": "http://www.tvtrailers.com/scenes/view/id/9422/title-2/",
          "text": "Title 2"
        },
        "pubDate": "February 6, 2016",
        "index": 2,
        "url": "http://www.tvtrailers.com/home/"
      },
      {
        "title": {
          "href": "http://www.tvtrailers.com/scenes/view/id/9358/title-3/",
          "text": "Title 3"
        },
        "pubDate": "February 5, 2016",
        "index": 3,
        "url": "http://www.tvtrailers.com/home/"
      },
      {
        "title": {
          "href": "http://www.tvtrailers.com/scenes/view/id/9419/title-4/",
          "text": "Title 4"
        },
        "pubDate": "February 5, 2016",
        "index": 4,
        "url": "http://www.tvtrailers.com/home/"
      }
    ]
  }
}

I'm trying to GET the value of href inside the title element, then explode the string to obtain the id number (9418, 9422, 9358, 9419 on the code above) and create a new property with just the id number.

Or, if is not possible to create a new property, then I would like to just replace all the href string and keep the id number instead of the full href url.

Here is the code I'm using: -Not working

function getpost_number(data) { 
    var post_number = 0; 
    for(var href in data.results) { 
        data.results[href].forEach(function(row) { 
            var parts = row.split("/"); 
            console.log(parts[5]+parts[6]); 
        }); 
    }; 
    data.post_number = post_number; 
    return data; 
}

Result:

{
  "error": "Bad Request",
  "message": "Your function failed to evaluate because of Error: Object object has no method 'split'"
}

Also the code inspector inside kimono had 2 warnings:

On line 7: Don't make functions within a loop.
On line 8: Unnecessary semicolon

I appreciate any help and directions to figure out what's wrong with the code above, thank you.

Addendum - new attempt

Here is the updated function I'm using with the code provided by Trincot on the comments below:

function addPostNumbers(data) {
    for(var collection in data.results) {
        data.results[collection].forEach(function(row) {
            if (parts = row.title.href.match(/\/(\d+)\//)) {
                row.title.post_number = parts[1];
            }
        });
    }
}

Output:

{
  "error": "Bad Request",
  "message": "Your function failed to evaluate because of Error: parts is not defined"
}

Kimono Inspector warnings

line 5: Assignment in conditional expression.
line 8: Don't make functions within a loop.

Upvotes: 0

Views: 134

Answers (2)

trincot
trincot

Reputation: 350147

The data you provided originally was not valid JSON, as it had more closing braces than opening ones, and it had some curly double quotes. This was fixed in your question later.

Here is a function that will add the post_number property in the title objects, provided that the href property contains a folder name that is numerical.

When you run this snippet, it will output the result (JSON) with the additional properties:

function addPostNumbers(data) {
    var collection, rows, i, parts;
    for (collection in data.results) {
        var rows = data.results[collection];
        for (i=0; i<rows.length; i++) {
            parts = rows[i].title.href.match(/\/(\d+)\//);
            if (parts) {
                rows[i].title.post_number = parts[1];
            }
        }
    }
    return data;
}

// test data
var data = {
  "name": "site update",
  "count": 4,
  "frequency": "Manual Crawl",
  "version": 1,
  "newdata": true,
  "lastrunstatus": "success",
  "thisversionstatus": "success",
  "thisversionrun": "Sun Feb 07 2016 05:13:26 GMT+0000 (UTC)",
  "results": {
    "collection1": [
      {
        "title": {
          "href": "http://www.tvtrailers.com/scenes/view/id/9418/title-1/",
          "text": "Title 1"
        },
        "pubDate": "February 6, 2016",
        "index": 1,
        "url": "http://www.tvtrailers.com/home/"
      },
      {
        "title": {
          "href": "http://www.tvtrailers.com/scenes/view/id/9422/title-2/",
          "text": "Title 2"
        },
        "pubDate": "February 6, 2016",
        "index": 2,
        "url": "http://www.tvtrailers.com/home/"
      },
      {
        "title": {
          "href": "http://www.tvtrailers.com/scenes/view/id/9358/title-3/",
          "text": "Title 3"
        },
        "pubDate": "February 5, 2016",
        "index": 3,
        "url": "http://www.tvtrailers.com/home/"
      },
      {
        "title": {
          "href": "http://www.tvtrailers.com/scenes/view/id/9419/title-4/",
          "text": "Title 4"
        },
        "pubDate": "February 5, 2016",
        "index": 4,
        "url": "http://www.tvtrailers.com/home/"
      }
    ]
  }
};

// don't add this to your code. Kimono will do this (I suppose):
addPostNumbers(data);

// write result in document, don't add this in your own code
document.write('<pre>' + JSON.stringify(data, null, 2) + '</pre>');

Concerning the warnings you received:

On line 7: Don't make functions within a loop.

You can ignore this warning. This is intended to avoid that the runtime has to create a function again and again, because it is defined within a loop. Here it concerns the forEach callback function, where the forEach call appears in a loop itself. However, with the forEach construct most runtimes will parse this efficiently.

On line 8: Unnecessary semicolon

This concerns the semi-colon after the closing brace of your for-loop. You should remove that one.

Addendum - feed back

You tried a previous version of my code (present now in your question) and listed some problems raised by Kimono, which seems to have its own Javascript parser and to apply stricter rules than the browser:

line 5: Assignment in conditional expression.

I have updated the above code, moving the assignment out of the conditional expression.

line 8: Don't make functions within a loop.

I had written earlier that this warning can be ignored, but now I have replaced the foreach loop as a standard for loop, so you should not get this warning any more.

line 16: document.write can be a form of eval

The calls to the functions addPostNumbers and document.write are only in my snippet to demo the solution. That part of the code is not intended to be used in your code.

"message": "Your function failed to evaluate because of Error: parts is not defined"

I added a var statement in the code above to avoid this.

I also added a return statement, as Kimono might need that as well, I don't know.

Upvotes: 0

Brandon Poe
Brandon Poe

Reputation: 481

Your row is going to look like this:

{
  "title": {
    "href": "http://www.tvtrailers.com/scenes/view/id/9358/title/“,
    "text": "Title 1"
  },
  "pubDate": "February 5, 2016",
  },
  "index": 1,
  "url": "http://www.tvtrailers.com/videos/thismonth/bydate/"
}

Which means you want to dig deeper and split on row.title.href

Also, I'm not sure which pieces your are hoping to retrieve, but parts[5] will equal "id" and parts[6] will equal 9358. That is because the // after http: will create an empty item between "http:" and "www.tvtrailers.com".

In other words you split array will look like this: ["http:", "", "www.tvtrailers.com", "scenes", "view", "id", "9358", "title", ""]

Upvotes: 0

Related Questions