Parse JSON from Jenkins, once hash, then nil - ruby

Jenkins gives me JSON from http://jenkins.net/jobs/MyJob/lastBuild/api/json
Then I use HTTParty to get it like so:
response = self.get( url, options )
change = response['changeSet']['items'][0]
This gives me the content of the last changes. change.class returns "Hash".
If I try this:
change = response['changeSet']['items'][0]['revision']
as looking at the JSON suggests, I get "Undefined method '[]' on NilObject".
What am I doing wrong?
EDIT3:
Of course, the problem lies between User and keyboard. The method was first called on another JSON, because it's polling the changes for more than one project, and one of the returned JSON objects didn't contain those keys. D'oh!
Sorry.

If you get that kind of error you're hitting an empty key and then trying to use it as if it's populated. Without seeing what your JSON is, it's hard to say, but one of those is failing. You'll want to inspect these:
response['changeSet']
response['changeSet']['items']
response['changeSet']['items'][0]
If any of those end up being nil then you can pin-point the problem. JSON comes back as an arbitrary structure so chaining a bunch of calls together without any sort of testing can lead to trouble.

Related

JSON Parsing a Redis.get return

I'm storing some data in Redis and when I retrieve this data I'm having trouble parsing it.
When I run this:
$redis.get("data") I get this: "[{\"login\"=>\"name\", \"id\"=>1574}]"
When I try to use JSON.parse against the return body I get this error:
JSON::ParserError: 409: unexpected token at '{"login"=>"name", "id"=>1574}]'
What am I doing wrong?
You need to first serialize your ruby object into JSON before storing it in redis.
In this case you would need to call $redis.set('data', JSON.dump(data)) instead of what is currently being called, which is $redis.set('data', data.to_s). The .to_s gets called on whatever object is passed into redis' set method.
If you really need to parse the data you have already stored then you can use ruby's eval, although you should not use this in production!
$ data = eval($redis.get('data'))
=> [{"login"=>"name", "id"=>1574}]
$ $redis.set('data', JSON.dump(data))
"[{\"login\"=>\"name\", \"id\"=>1574}]"
is not json string
If you want to deserialize string then you write this.
"[{\"login\":\"name\", \"id\":1574}]"
=> is changed to :
So, you need to modify the creation JSON string.

Passing values between cucumber statements

I'm running in to an issue in that I need to get one value in a cucumber statement, and then give that value to another statement.
Specifically I am getting a JSON object from one page (where that object gets sent to an api endpoint as a preference) and then using information out of that after I query the api, which happens in a completely separate step.
I am suspecting that I have to write the value somewhere, and then pull that value when the step that needs it comes up, but I'm kind of at a loss for doing that as well.
I can provide any further needed details, thanks for any help!
Definitely a rookie question - to which the answer is to use instance variables - #variable_name = get_method in the helper method your step calls.

How can I use a list function in CouchDB to generate a valid (/normal) ViewResults object?

I have a simple problem I need to solve, and list functions are my current attempt to do so. I have a view that generates almost what I need, but in certain cases there are duplicate entries that make it through when I send in edge-case parameters.
Therefore, I am looking to filter these extra results out. I have found examples of filtering, which I am using (see this SO post). However, rather than generate HTML or XML or what-have-you, I just want a regular ol' view result. That is, the same kind of object that I would get if I queried CouchDB without a list function. It should have JSON data as normal and be the same in every way, except that it is missing duplicate results.
Any help on this would be appreciated! I have tried to send() data in quite a few different ways, but I usually get that "No JSON object could be decoded", or that indices need to be integers and not strings. I even tried to use the list to store every row until the end and send the entire list object back at once.
Example code (this is using an example from this page to send data:
function(head, req) {
var row; var dupes = [];
while(row=getRow()) {
if (dupes.indexOf(row.key) == -1) {
dupes.push(row.key);
send(row.value);
}
};
}
Lastly, I'm using Flask with Flask-CouchDB, and I'm seeing the aforementioned errors in the flask development server that I'm running.
Thanks! I can try to supply more details if need be.
Don't you need to prepend a [, send a , after each row value except the last, and end with ]? To actually mimic a view result, you'd actually need to wrap that in a JSON structure:
{"total_rows":0,"offset":0,"rows":[<your stuff here>]}

How do I parse a POST to my Rails 3.1 server manually?

Scenario:
I have a Board model in my Rails server side, and an Android device is trying to post some content to a specific board via a POST. Finally, the server needs to send back a response to the Android device.
How do I parse the POST manually (or do I need to)? I am not sure how to handle this kind of external request. I looked into Metal, Middleware, HttpParty; but none of them seems to fit what I am trying to do. The reason I want to parse it manually is because some of the information I want will not be part of the parameters.
Does anyone know a way to approach this problem?
I am also thinking about using SSL later on, how might this affect the problem?
Thank you in advance!! :)
I was trying to make a cross-domain request from ie9 to my rails app, and I needed to parse the body of a POST manually because ie9's XDR object restricts the contentType that we can send to text/plain, rather than application/x-www-urlencoded (see this post). Originally I had just been using the params hash provided by the controller, but once I restricted the contentType and dataType in my ajax request, that hash no longer contained the right information.
Following the URL in the comment above (link), I learned the how to recover that information. The author mentions that in a rails controller we always have access to a request variable that gives us an instance of the ActionDispatch::Request object. I tried to use request.query_string to get at the request body, but that just returned an empty string. A bit of snooping in the API, though, uncovered the raw_post method. That method returned exactly what I needed!
To "parse it manually" you could iterate over the string returned by request.raw_post and do whatever you want, but I don't recommend it. I used Rack::Utils.parse_nested_query, as suggested in Arthur Gunn's answer to this question, to parse the raw_post into a hash. Once it is in hash form, you can shove whatever else you need in there, and then merge it with the params hash. Doing this meant I didn't have to change much else in my controller!
params.merge!(Rack::Utils.parse_nested_query(request.raw_post))
Hope that helps someone!
Not sure exactly what you mean by "manually", posts are normally handled by the "create" or "update" methods in the controller. Check out the controller for your Board model, and you can add code to the appropriate method. You can access the params with the params hash.
You should be more specific about what you are trying to do. :)

GET vs POST in AJAX?

Why are there GET and POST requests in AJAX as it does not affect page URL anyway? What difference does it make by passing sensitive data over GET in AJAX as the data is not getting reflected to page URL?
You should use the proper HTTP verb according to what you require from your web service.
When dealing with a Collection URI like: http://example.com/resources/
GET: List the members of the collection, complete with their member URIs for further navigation. For example, list all the cars for sale.
PUT: Meaning defined as "replace the entire collection with another collection".
POST: Create a new entry in the collection where the ID is assigned automatically by the collection. The ID created is usually included as part of the data returned by this operation.
DELETE: Meaning defined as "delete the entire collection".
When dealing with a Member URI like: http://example.com/resources/7HOU57Y
GET: Retrieve a representation of the addressed member of the collection expressed in an appropriate MIME type.
PUT: Update the addressed member of the collection or create it with the specified ID.
POST: Treats the addressed member as a collection in its own right and creates a new subordinate of it.
DELETE: Delete the addressed member of the collection.
Source: Wikipedia
Well, as for GET, you still have the url length limitation. Other than that, it is quite conceivable that the server treats POST and GET requests differently; thus the need to be able to specify what request you're doing.
Another difference between GET and POST is the way caching is handled in browsers. POST response is never cached. GET may or may not be cached based on the caching rules specified in your response headers.
Two primary reasons for having them:
GET requests have some pretty restrictive limitations on size; POST are typically capable of containing much more information.
The backend may be expecting GET or POST, depending on how it's designed. We need the flexibility of doing a GET if the backend expects one, or a POST if that's what it's expecting.
It's simply down to respecting the rules of the http protocol.
Get - calls must be idempotent. This means that if you call it multiple times you will get the same result. It is not intended to change the underlying data. You might use this for a search box etc.
Post - calls are NOT idempotent. It is allowed to make a change to the underlying data, so might be used in a create method. If you call it multiple times you will create multiple entries.
You normally send parameters to the AJAX script, it returns data based on these parameters. It works just like a form that has method="get" or method="post". When using the GET method, the parameters are passed in the query string. When using POST method, the parameters are sent in the post body.
Generally, if your parameters have very few characters and do not contain sensitive information then you send them via GET method. Sensitive data (e.g. password) or long text (e.g. an 8000 character long bio of a person) are better sent via POST method.
Thanks..
I mainly use the GET method with Ajax and I haven't got any problems until now except the following:
Internet Explorer (unlike Firefox and Google Chrome) cache GET calling if using the same GET values.
So, using some interval with Ajax GET can show the same results unless you change URL with irrelevant random number usage for each Ajax GET.
Others have covered the main points (context/idempotency, and size), but i'll add another: encryption. If you are using SSL and want to encrypt your input args, you need to use POST.
When we use the GET method in Ajax, only the content of the value of the field is sent, not the format in which the content is. For example, content in the text area is just added in the URL in case of the GET method (without a new line character). That is not the case in the POST method.

Resources