The situation is as follows:
There is a text. Every text change, and I submit a request.
The response text is divided into parts.
Then I send each part to the server again.
Example:
Request - Response
1234567 => [1], [2], [3,4], [5, 6, 7]
Request Queue
[1] => [2] => [3,4] => [5,6,7]
Change the text
Request - Response
12334567 => [1], [2], [3,3,4], [5, 6, 7]
Here I want to compare prev answer with new one, to send only
[3, 3, 4]
I decided to make it all as stream, and finally deal with RxJS.
Actually looking for RxJS way
I will suggest an alternative here. Instead of caching the response array, cache the response of HTTP request you make using an Interceptor. Simple map will be a good choice for a cache. If you are using Angular see the code below, it provides Intercepts out of the box.
If you make an HTTP request for [1] for example save it in a cache
intercept(req: HttpRequest<any>, next: HttpHandler) {
const response = this.cache.get(req); // get the cached response object.
return response? Observable.of(response) : makeHttpRequest(req,next)
}
makeRequest(req, next){
//make http request and save it in cache as well,
const response = httpREquest();
this.cache.put(req, response);
}
From your example when request for [3,3,4] is made, no output in cache found, make an http request and save it. This way you will avoid array comparison.
Related
I would like to do sequential HTTP calls and merge the responses into one and unique observable.
Problem is: the way I am doing it seems to be wrong. Indeed, I would like to merge the data from the second request into the first one, but the way I did it seems to replace the result of the first one by the result of the seconde one.
Here it is the first request called:
[{vehicule_id:123, statistics:{speed:60,rotation:38}},...]
The second one:
[{vehicule_id:123, name:"name",description:"description},...]
And the result I would like to get:
[{vehicule_id:123, statistics:{speed:60,rotation:38}, name:"name",description:"description},...]
Important thing to know: the second request needs a vehicule_id provided in the response of the first one.
With my code, the response of the second call replace the result of the first one instead of merging them.
Here it is my code:
getUserVehiculesInfo(user_id: number, language: string): void {
this._data.getUserVehiculesInfo(user_id, language)
.pipe(
map(res => res.data[user_id]),
switchMap(vehicules => forkJoin(vehicules.map(vehicule => this._data.getVehiculesInfo(tank.vehicule_id, language)))),
tap(console.log)
)
.subscribe();
}
Once you have the vehiculesInfo (the result of the forkJoin, you simply need to combine them with the vehicules:
switchMap(
vehicules => forkJoin(...).pipe(
map(infos => combineVehiculesAndInfos(vehicules, infos))
)
)
I'm using Sinatrarb to complete a task
I need to:
Parse the data of a JSON object from a url,
Single out one of attributes of the json data and store it as a variable
Run some arithmetic on the variable
Return the result as a new variable
then post this to a new url as a new json object.
I have seen bits and pieces of information all over including information on parsing JSON data in ruby and information on open-uri but I believe it would be very valuable having someone break this down step by step as most similar solutions given to this are either outdated or steeply complex.
Thanks in advance.
Here's a simple guide. I've done the same task recently.
Let's use this JSON (put it in a file called 'simple.json'):
{
"name": "obscurite",
"favorites": {
"icecream": [
"chocolate",
"pistachio"
],
"cars": [
"ferrari",
"porsche",
"lamborghini"
]
},
"location": "NYC",
"age": 100}
Parse the data of a JSON object from a url.
Step 1 is to add support for JSON parsing:
require 'json'
Step 2 is to load in the JSON data from our new .json file:
json_file = File.read('simple.json')
json_data = JSON.parse(json_file)
Single out one of attributes of the json data and store it as a variable
Our data is in the form of a Hash on the outside (curly braces with key:values). Some of the values are also hashes ('favorites' and 'cars'). The values of those inner hashes are lists (Arrays in Ruby). So what we have is a hash of hashes, where some hashes are arrays.
Let's pull out my location:
puts json_data['location'] # NYC
That was easy. It was just a top level key/value. Let's go deeper and pull out my favorite icecream(s):
puts json_data['favorites']['icecream'] # chocolate pistachio
Now only my second favorite car:
puts json_data['favorites']['cars'][1] # porsche
Run some arithmetic on the variable
Step 3. Let's get my age and cut it down by 50 years. Being 100 is tough!
new_age = json_data['age'] / 2
puts new_age
Return the result as a new variable
Step 4. Let's put the new age back into the json
json_data['age'] = new_age
puts json_data['age'] # 50
then post this to a new url as a new json object.
Step 5. Add the ability for your program to do an HTTP POST. Add this up at top:
require 'net/http'
and then you can post anywhere you want. I found a fake web service you could use, if you just want to make sure the request got there.
# use this guy's fake web service page as a test. handy!
uri = URI.parse("http://jsonplaceholder.typicode.com/posts")
header = {'Content-Type'=> 'text/json'}
http = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Post.new(uri.request_uri, header)
request.body = json_data.to_json
response = http.request(request)
# Did we get something back?
puts response.body
On linux or mac you can open a localhost port and listen as a test:
nc -4 -k -l -v localhost 1234
To POST to this port change the uri to:
uri = URI.parse("http://localhost:1234")
Hope this helps. Let me know if you get stuck and I'll try to lend a hand. I'm not a ruby expert, but wanted to help a fellow explorer. Good luck.
I am building an API wrapper and am writing some tests for it and I have a couple of questions.
1) How do I write an assert for calls where data doesn't exist? For example, looking up a member by id using the API but the user won't exist yet.
2) How do I write an assert for testing PUT and DELETE requests?
I already have a grasp on testing GET and POST requests just not sure on the other 2 verbs.
For your question part 1...
You have a couple choices for data that doesn't exist:
You can create the data ahead of time, for example by using a test seed file, or a fixture, or a factory. I like this choice for larger projects with more sophisticated data arrangements. I also like this choice for getting things working first because it's more straightfoward to see the data.
You can create a test double, such as a stub method or fake object. I like this choice for fastest test performance and best isolation. For fastest tests, I intercept calls as early as possible. The tradeoff is that I'm not doing end-to-end testing.
For your question part 2...
You should edit your question to show your actual code; this will help people here answer you.
Is your VCR code is something like this?
VCR.use_cassette('test_unit_example') do
response = Net::HTTP.get_response('localhost', '/', 7777)
assert_equal "Hello", response.body
end
If so, you change the HTTP get to put, something like this:
uri = URI.parse(...whatever you want...)
json = "...whatever you want..."
req = Net::HTTP::Put.new(uri)
req["content-type"] = "application/json"
req.body = json
request(req)
Same for HTTP delete:
Net::HTTP::Delete.new(uri)
A good blog post is the http://www.rubyinside.com/nethttp-cheat-sheet-2940.html>Net::HTTP cheat sheet excerpted here:
# Basic REST.
# Most REST APIs will set semantic values in response.body and response.code.
require "net/http"
http = Net::HTTP.new("api.restsite.com")
request = Net::HTTP::Post.new("/users")
request.set_form_data({"users[login]" => "quentin"})
response = http.request(request)
# Use nokogiri, hpricot, etc to parse response.body.
request = Net::HTTP::Get.new("/users/1")
response = http.request(request)
# As with POST, the data is in response.body.
request = Net::HTTP::Put.new("/users/1")
request.set_form_data({"users[login]" => "changed"})
response = http.request(request)
request = Net::HTTP::Delete.new("/users/1")
response = http.request(request)
I tried using window.postMessage but this only sends a variable (containing string) to the contentScript. But I want to send a number of variables' values. This seems to be possible by using a JSON object.
Simply use JSON.stringify() to turn the object into a string:
var data = {a: 1, b: 2};
window.postMessage(JSON.stringify(data), "*");
On the other end use JSON.parse() to reverse the process:
var data = JSON.parse(message);
If you use:
self.port.emit('some-event', object)
...and only send objects that can be serialized into JSON properly, the SDK will handle serialization and parsing for you. Here's a quick builder example that illustrates this:
https://builder.addons.mozilla.org/addon/1036506/latest/
I had thought that postMessage would be the same?
I'm using sendgrid's event api which sends a codeblock like this to a postback url of my choice:
Array
(
[email] => fgdfg#gmail.com
[timestamp] => 1323698899
[smtp-id] => <4ee60acf8e3d1_55dd862cf147044#mbjoppa.mail>
[response] => 250 2.0.0 OK 1323698899 o30s15072o427yhl.103
[event] => delivered
)
They don't have XML or JSON and I need to extract the email and event parts of this block.
Any idea how I do this with rails? Basically this block is sent to a postback URL of my choice but I'm not sure how to use it from there.
I never used sendgrid but after a quick look it seems like they are just sending you a standard post request with parameters so you best bet is to define a simple action like the following and see what you get:
def sendgrid_event
Rails.logger.info(params)
# chances are that this will contains what you are looking for:
# params['email']
# params['event']
end