Rx Js - create an observer for $.ajax Complete() - ajax

I have an ajax call for an insert operation. I need to update a grid (future there might be many) once the ajax call completed. How to do this using Rx Js.
I have done something with event based but it won't work out for my case.
NOTE: save ajax call is in different script file.
var submitButton = document.querySelector('.btn-primary');
var refresh1ClickStream = Rx.Observable.fromEvent(submitButton, 'click');
var requestStream = refresh1ClickStream.startWith('startup click')
.map(function () {
var max = 10;
return 'http://localhost/.../GetPayments';
});
var responseStream = requestStream
.flatMap(function (requestUrl) {
return Rx.Observable.fromPromise($.getJSON(requestUrl));
});
function createSuggestionStream(closeClickStream) {
return closeClickStream.startWith('startup click')
.combineLatest(responseStream,
function (click, data) {
return data;
}
)
.merge(
refresh1ClickStream.map(function () {
return null;
})
)
.startWith(null);
}
var paymentStream = createSuggestionStream(refresh1ClickStream);
//var pfaStream = createSuggestionStream(refresh1ClickStream);
// Rendering ---------------------------------------------------
function renderSuggestion(payments, selector) {
//render grid
}
paymentStream.subscribe(function (payment) {
renderSuggestion(payment, 'payment1');
});
//pfaStream.subscribe(function (pfa) {
// renderSuggestion(pfa, 'tblPayFromAccount');
//});

Related

sending and recieving files through RestBulider

controller on localhost:8000
const fs = require("fs");
exports.install = function () {
ROUTE("GET /", indexPage);
};
function indexPage() {
var self = this;
console.log(" In GET ROUTE");
RESTBuilder.GET("http://127.0.0.1:8500/getFile/").stream(function (
err,
response
) {
if (err) {
console.log(err);
return;
}
var writer = fs.createWriteStream("./public/testBuilder.txt");
// console.log("Writing to file");
response.pipe(writer);
self.json({ thankyou: "ok" });
});
}
controller on localhost:8500
exports.install = function () {
ROUTE("GET /getFile/", test);
};
function test() {
var self = this;
console.log("#################");
console.log(self.body);
self.file("~trimSail/restBuilder.txt");
// });
}
above code works in totaljs 3 but failing in total4.
sending a file in response to RestBuilder.GET and streaming the response to file.
error response.pipe is not a function.
First of all, please clean your code.
Total.js guidelines https://docs.totaljs.com/welcome/67b47001ty51c/
Optimized for Total.js:
const Fs = require('fs');
exports.install = function () {
ROUTE('GET /', index);
};
function index() {
var $ = this;
console.log('In GET ROUTE');
RESTBuilder.GET('http://127.0.0.1:8500/getFile/').stream($.successful(function(response) {
var writer = Fs.createWriteStream('./public/testBuilder.txt');
response.stream.pipe(writer);
$.json({ thankyou: 'ok' });
}));
}

Nodejs - xmlhttprequest promise never finish

module.js
var Promise = require('bluebird');
var XMLHttpRequest = require('xhr2');
function fetchdata(id) {
var url = 'http://www.youtube.com/watch?v=' + id;
return new Promise(function (fulfill, reject) {
var xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.onload = function() {
var jsonStr;
try {
fulfill(xhr.response);
} catch (e) {
reject(jsonStr);
}
};
xhr.onerror = function(e) {
reject(e);
};
xhr.send('');
});
}
module.exports = {
getdata: function (videoID) {
return new Promise(function (fulfill, reject) {
if (!videoID) {
reject(new Error('Unable to get video id.'));
return;
}
fetchdata(videoID).then(
function (d) {
console.log( d);
}
);
});
}
};
index.js
var parser = require('./module.js');
parser.getdata("ZI4tRn4dOGg", function (data) {
console.log(data);
}
)
I tried to get youtube view page source code with xmlhttprequest.
BUT above code does not finish. I guess it is waiting for something.
Is problem from bluebird? or xhr2? and why does this code never finish?
Your xhr instance had a memory leak, might be a problem with the library, last publish was a year ago. Bluebird was ok. You can fix the hangup by using node-fetch and dropping in this replacement for fetchdata
const fetch = require('node-fetch')
function fetchdata(id) {
var url = 'http://www.youtube.com/watch?v=' + id;
return fetch(url).then(res => res.text())
}

fetch returning promise rather than value

Hopefully the code below communicates the problem clearly. The issue is that in the module which uses the get method of fetchData, the value being returned is the actual Promise, rather than the JSON as desired. Any thoughts on this?
// fetchData.js module
var _ = require('lodash');
function get() {
var endpoint1 = `/endpoint1`;
var endpoint2 = `/endpoint2`;
return fetch(endpoint1)
.then((endpoint1Response) => {
return endpoint1Response.json()
.then((endpoint1JSON) => {
return fetch(endpoint2)
.then((endpoint2Response) => {
return endpoint2Response.json()
.then((endpoint2JSON) => {
var data = _.merge({}, {json1: endpoint1JSON}, {json2: endpoint2JSON});
console.log('data in fetch', data); // this logs the json
return data;
});
});
});
});
}
exports.get = get;
// module which uses get method of fetchData get
var fetchData = require('fetchData');
var data = fetchData.get();
console.log('returned from fetchData', data); // this logs a Promise
Yes, that's exactly what's supposed to happen. The whole point of promises is that their result value is not immediately available and that doesn't change just because you're obtaining one from a separate module.
You can access the value like this:
var fetchData = require('fetchData');
fetchData.get().then(data =>
console.log('returned from fetchData', data);
);
Also note that you are using promises in a non-idiomatic way and creating a "tower of doom." This is much easier on the eyes and accomplishes the same thing:
function fetchJson(endpoint) {
return fetch(endpoint)
.then(endpointResponse => endpointResponse.json());
}
function get() {
var endpoint1 = `/endpoint1`;
var endpoint2 = `/endpoint2`;
return Promise.all([fetchJson(endpoint1), fetchJson(endpoint2)])
.then(responses => {
var data = { json1: responses[0], json2: responses[1] };
console.log('data in fetch', data); // this logs the json
return data;
});
}
Edit I haven't used async/await in JavaScript, but to answer your question, I presume this would work:
async function fetchJson(endpoint) {
var res = await fetch(endpoint);
return res.json();
}
async function get() {
var endpoint1 = `/endpoint1`;
var endpoint2 = `/endpoint2`;
var data = {
json1: await fetchJson(endpoint1),
json2: await fetchJson(endpoint2)
};
console.log('data in fetch', data); // this logs the json
return data;
}
// module which uses get method of fetchData get
async function main() {
var fetchData = require('fetchData');
var data = await fetchData.get();
console.log('returned from fetchData', data);
}
return main();

Knockout JS - update viewModel with AJAX Call

there are some similar questions but didn't help me to solve my issue. I can't update my results on page / view after updating my viewModel with AJAX. I am getting valid AJAX response that updates the view if I reload the page, but not when I click btnAdvancedSearch
I have simple HTML:
<div>
<input type="button" id="btnAdvancedSearch" data-bind="click: refresh" />
</div>
<div id="resultslist1" data-bind="template: { name: 'rest-template', foreach: restaurants }">
</div>
And I bind in on document load:
$(document).ready(function () {
ko.applyBindings(new RestaurantsListViewModel());
});
My viewModel is like this, and in it I call refresh that is bound with button
// Overall viewmodel for this screen, along with initial state
function RestaurantsListViewModel() {
var self = this;
self.restaurants = ko.observableArray([]);
var mappedRests = $.map($.parseJSON(sessionStorage.getItem('searchResults')), function (item) { return new Restaurant(item) });
self.restaurants = mappedRests;
self.refresh = function () {
updateRestaurantsList(); //Method executes AJAX and saves result to session.
var mappedRests2 = $.map($.parseJSON(sessionStorage.getItem('searchResults')), function (item) { return new Restaurant(item) });
self.restaurants= mappedRests2;
}
}
What am I missing here?
Thanks
I have tried waiting for AJAX to finish like this:
// Overall viewmodel for this screen, along with initial state
function RestaurantsListViewModel() {
var self = this;
self.restaurants = ko.observableArray([]);
var mappedRests = $.map($.parseJSON(sessionStorage.getItem('searchResults')), function (item) { return new Restaurant(item) });
self.restaurants = mappedRests;
self.refresh = function () {
var latitude = sessionStorage.getItem('latitude');
var longitude = sessionStorage.getItem('longitude');
var query = '{"Accepts_Reservations":"' + $('#chkReservation').is(":checked") + '","Accepts_Cards":' + $('#chkAcceptsCards').is(":checked") + '"}';
var searchResults = getRestaurantsAdvancedSearchAJAX(query, latitude, longitude, 40);
searchResults.success(function (data) {
var information = data.d;
var mappedRests2 = $.map($.parseJSON(information), function (item) { return new Restaurant(item) });
self.restaurants = mappedRests2;
});
};
};
Edit 1
Once you have declared your observable like so:
self.restaurants = ko.observableArray([]);
When you want to update restaurants you cannot do this:
self.restaurants = mappedRests2;
Instead, you need to do this:
self.restaurants(mappedRests2);
updateRestaurantsList(); //Method executes AJAX and saves result to session.
The comment after the above line indicates that this method is making an asynchronous call. Therefore, it is likely that the line after it is executing before sessionStorage has been populated. Maybe consider having updateRestaurantsList return a promise. Then you could update your code to something like this:
updateRestaurantsList().then(function() {
var mappedRests2 = $.map($.parseJSON(sessionStorage.getItem('searchResults')), function (item) { return new Restaurant(item) });
self.restaurants= mappedRests2;
});
This way the call to populate your mappedRests2 variable won't happen until after your updateRestaurantsList method has completed.
Edit 1
Be sure to never assign values to an observable using an equal sign.
// Overall viewmodel for this screen, along with initial state
function RestaurantsListViewModel() {
var self = this;
self.restaurants = ko.observableArray([]);
var mappedRests = $.map($.parseJSON(sessionStorage.getItem('searchResults')), function (item) { return new Restaurant(item) });
self.restaurants(mappedRests);
self.refresh = function () {
var latitude = sessionStorage.getItem('latitude');
var longitude = sessionStorage.getItem('longitude');
var query = '{"Accepts_Reservations":"' + $('#chkReservation').is(":checked") + '","Accepts_Cards":' + $('#chkAcceptsCards').is(":checked") + '"}';
var searchResults = getRestaurantsAdvancedSearchAJAX(query, latitude, longitude, 40);
searchResults.success(function (data) {
var information = data.d;
var mappedRests2 = $.map($.parseJSON(information), function (item) { return new Restaurant(item) });
self.restaurants(mappedRests2);
});
};
};

Node JS - get file via AJAX and then use the data

How do I do this asynchronously?
var getData, myFunc;
getData = function() {
var data = "";
$.get("http://somewhere.com/data.xml", function(d) {
data = $("#selector", d).html();
});
return data; // does not work, because async callback not yet fired
};
myFunc = function() {
var data = getData();
// do something with data here
};
I am happy to completely re-factor to achieve what I want. I am just don't know what design pattern achieves this.
Well, you can't. You can return a promise though:
var getData, myFunc;
getData = function () {
var d = $.Deferred();
$.get("http://somewhere.com/data.xml", function (data) {
d.resolve($("#selector", data).html())
});
return d.promise();
};
getData().then(function (data) {
alert(data);
});
demo http://jsfiddle.net/W75Kt/2/

Resources