RxJs - Convert Flickr request to stream of photos - javascript

I'm a RXJS newbie.
Trying to figure out why this code doesn't work.
var $sources = $('#clickme');
var flickrApi = "https://api.flickr.com/services/rest/?method=flickr.photos.search&api_key=af11a8fa73ca2894e2f7c46ecd7a5a87&text=puppies&per_page=5&format=json&nojsoncallback=1";
Rx.Observable.fromEvent($sources, 'click')
.flatMap(click => Rx.Observable.fromPromise($.getJSON(flickrApi)))
.flatMap(response => Rx.Observable.fromArray(response.photos))
.subscribe(photo => console.log("The photo Object", photo));
The object is to run this flickr api, receive the photos and create a stream of single photo events.
For some reason subscribe doesn't happen.
Live (non-working) demo here: http://jsbin.com/pesiqo/2/edit
Thanks!

Your code is not valid JavaScript (JavaScript does not have lambdas).
You should also supply an error handler to your subscribe call to catch any runtime errors that occur. And you should check the response from Flickr to see if the request succeeded.
Just changing your code to valid JavaScript and it runs just fine, though it fails due to an invalid flickr API key.
var $sources = $('#clickme');
var flickrApi = "https://api.flickr.com/services/rest/?method=flickr.photos.search&api_key=af11a8fa73ca2894e2f7c46ecd7a5a87&text=puppies&per_page=5&format=json&nojsoncallback=1";
Rx.Observable.fromEvent($sources, 'click')
.flatMap(function (click) {
return Rx.Observable.fromPromise($.getJSON(flickrApi));
})
.flatMap(function (response) {
if (response.stat === "fail") {
return Rx.Observable.throw(new Error(response.message));
}
return Rx.Observable.fromArray(response.photos);
})
.subscribe(function (photo) {
console.log("The photo Object", photo);
}, function (error) {
console.log("an error occurred", error, error.message, error.stack);
});
jsbin: http://jsbin.com/tupowacila/3/edit

Related

Can we reset streamwriter data for inbound integration?

Just wondering if we are able to re-write data that we was set via the setWriteString() method while responding to an inbound api call. For example, let's say the scripted rest resource code is as follows:
(function process(/*RESTAPIRequest*/ request, /*RESTAPIResponse*/ response) {
var body = request.body.data;
/* do something with request data
..
..
..
then start preparing the response
*/
var writer = response.getStreamWriter();
try
{
response.setContentType('application/json');
response.setStatus(200);
writer.writeString("{\"results\":[");
var inc = new GlideRecord('incident');
inc.query();
while(inc.next()){
var obj = {};
obj.id = inc.getValue('number');
obj.sys_id = inc.getUniqueValue();
writer.writeString(global.JSON.stringify(obj));
if (inc.hasNext()) {
writer.writeString(",");
}
}
writer.writeString("]}");
}
catch (ex)
{
// let's say exception was thrown on the 3rd iteration while gliding the incident table
// oh no...an exception..so we need to write something else to the stream
// is it possible to erase/remove everything that was added to the stream up until the exception occured?
// so that the response will contain details only about the error?
// something like below:
response.setContentType('application/json');
response.setStatus(500);
writer.writeString("{\"error\":\"Something went wrong\"}"); // this isn't working btw...the stream contained both the content generated in "try" block as well as the "catch" block
// this should not contain anything related to whatever was written from the earlier iterations....
}
})(request, response);
For the errors you can use the Scripted REST API Error objects.
Which should reset the output stream.
https://developer.servicenow.com/dev.do#!/learn/courses/paris/app_store_learnv2_rest_paris_rest_integrations/app_store_learnv2_rest_paris_scripted_rest_apis/app_store_learnv2_rest_paris_scripted_rest_api_error_objects
(function run(request, response) {
try {
...
} catch (e) {
var myError = new sn_ws_err.ServiceError();
myError.setStatus(500);
myError.setMessage('Something went wrong');
myError.setDetail('Error while retrieving your data: ' + e);
return myError;
}
})(request,response);
It might also be useful to get the error message from the GlideRecord
gr.getLastErrorMessage();
// something like aborted by businessrule or acl, etc...
For the details of your error message.

Error callback using echo-laravel and react

I'm trying to add a callback for a pusher:subscription_error with echo-laravel. The client is done in react. The broadcaster is Pusher and I subscribe to a channel like this:
echo.private('User.' + this.props.user.id).listen("NewMessage", (newMessage) => {
if (newMessage.message.message_room_id === this.state.selectedMessage.id) {
this.props.newMessageInOpenBox(newMessage);
} else {
this.props.newMessage(newMessage);
}
}
)
Im trying to get the failed subscription callback working so i can trigger a token refresh. How would i catch the subscription error? i couldn't find anything in the docs or elsewhere.
for anyone having the same problem i found that you have to go into the channel like this
echo.connector.pusher.channels.channels['private-' + channelName].bind('pusher:subscription_error', () => {
alert('sub error')
})

Add Firebase Firestore DB listener from Node.js Cloud Function

My issue, cannot read the data from the write DB callback, check below for more details
I am using firestore with node.js cloud function, and I need to set DB listener to messages collection, below is the code of setting listener to the data and the data structure, and my issue that I cann please check the following data structure
Here is the second level and the added message
exports.sendNotificationDependsOnEvent = functions.firestore.document('events/{event}/messages/{message}')
.onCreate((snap, context) => {
const document = snap.val();
// I tried snap.val() and it's not worked
//and I tried snap.data (give me very long un related data)
//and I tried snap.data() and it throwing exception (data is not a function)
//and I tried snap.current.val (and no result for that)
const text = document.message;
console.log("Step 3 : get message text : " + text);
});
advise how can I read data from above data
Your problem most probably comes from the fact that snap does not exist. You may have an error in the way you build the reference.
As detailed in the doc (https://firebase.google.com/docs/firestore/query-data/get-data#get_a_document) it is recommended to check if the doc exist before trying to get its field values.
See this example (for node.js) from the doc referenced above:
var cityRef = db.collection('cities').doc('SF');
var getDoc = cityRef.get()
.then(doc => {
if (!doc.exists) {
console.log('No such document!');
} else {
console.log('Document data:', doc.data());
}
})
.catch(err => {
console.log('Error getting document', err);
});
Can you check, in your code, if snap really exist, as follow?
exports.sendNotificationDependsOnEvent = functions.firestore.document('events/{event}/messages/{message}')
.onCreate((snap, context) => {
if (!snap.exists) {
console.log('No such document!');
} else {
console.log('Document data:', snap.data());
}
});
The console will log in the Functions Log.

Understanding Error Propogation in Node

I'm using the Google Maps API with Node to get the formatted address of a particular location. The Maps API returns an empty array when no matching location can be found, so I'm trying to throw an error when the response array is empty using the following code:
function timeZoner(queryString) {
const mapsApiKey = 'API_KEY';
const googleMapsClient = require('#google/maps').createClient({
key: mapsApiKey
});
const VError = require('VError');
googleMapsClient.geocode({
address: queryString
}, function(err, response) {
if (!err) {
returnedResults = response.json.results;
if (returnedResults.length < 1) {
console.log('no match found');
var err1 = new Error;
}
var err2 = new VError(err1, 'no matched location');
console.log(err2.message);
} else {
console.log('Maps API error');
}
});
};
timeZoner('this location name will not match');
Based on the example above, console will log 'no match found' as expected, but err1 is never set, or at least isn't triggering err2 and logging its message in the console as I think it should based on the VError docs. Can someone offer insight on why the error isn't getting triggered?
I'm having trouble wrapping my head around errors in Node as I'm relatively new to JS and I'm brand new to Node. I am aware of error-first callbacks and see that the fact that googleMapsClient.geocode might be the reason the error isn't triggering, but I thought VError was supposed to assist with this. I appreciate any help.

Disable Display of Generic Browser Push Notification

I have implemented the browser push notification functionality and its working fine. I used this guide as the reference https://developers.google.com/web/fundamentals/getting-started/push-notifications/step-01?hl=en
However as payload is still not supported, I decided to query my server to get the notification data for each user which is also working fine.
There is one issue though. For some cases, after getting data from the server, I want to control whether to show the notification or not. I am not able to figure out how to do this. I tried returning false, throwing errors etc. But is always shows the default notification even if I don't call showNotification method. Let me know how to solve this. Following is the relevant code
self.addEventListener('push', function(event) {
event.waitUntil(
fetch('/getPushNotificationData/').then(function(response){
if (response.status !== 200) {
// I don't want to show any notification in this case
console.log('Looks like there was a problem. Status Code: ' + response.status);
throw new Error();
}
return response.json().then(function(data){
var shouldDisplay = data.shouldDisplay;
if (shouldDisplay=='1'){
var title = data.title;
var message = data.message;
var url = data.url;
return self.registration.showNotification(title, {
body: message,
data: url
});
}
else{
// I don't want to show any notification in this case also
return true;
}
});
})
);
});

Categories