Electron js win.webContents.print callback function doesn't work? - javascript

I am working on an application with Electron js and Vue js. I need to print the Synchronous request sent by Renderer with the print function. According to the result, I have to transmit the result to the renderer over the backend. Therefore, I use the callback function of the print function. But when I use this function, the print method does not work. I shared the codes below. Could there be an error?
ipcMain.on("set-print", function(event, arg) {
let options = {
silent: true,
deviceName: arg,
};
win.webContents.print(options, function(success) {
event.returnValue = success;
});
});

Try Promise function
win.webContents.print(options)
.then((success)=>{
console.log(success);
})
.catch((err)=>{
console.log(err)
});
https://www.electronjs.org/docs/api/webview-tag#webviewprintoptions

Related

Handle ajax errors and execute the promise chain

I'm trying to provide a fallback for the failed ajax requests.
I want a global solution so I won't have to change every call in the code.
I tried providing an error handler to ajaxSetup, but the problem is I couldn't execute the chained callbacks.
$.ajaxSetup({
error: function() {
console.error('Error occurred')
return $.getJSON('https://jsonplaceholder.typicode.com/todos/1')
}
})
$.getJSON('https://jsonplaceholder.typicode.com/todos/0') // Id doesn't exist
.then(todo => console.log(todo))
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Expected output
Error occurred
{
"id": 1,
"title": "...",
...
}
From jQuery 3.0 the callback method accepted are: done, always, fail.
So, i would have called the callback fail and in the inner, i resend the ajax call wrapped into a properly function with dynamic id
const submit = (id) => {
const xhr = $.getJSON(`https://jsonplaceholder.typicode.com/todos/${id}`)
.done(todo => console.log(todo))
.fail(err => { console.error(err); submit(id++); });
};
submit(0);

using bluebird with undefined success callback function

I am using bluebird library over memcached.
memcached.set('foo', 'bar', 10, function (err) { /* stuff */ });
this function does not call success callback in second parameter so seems like .then(res) function does not getting called.
Promise.promisifyAll(memcached);
memcached.setAsync(hashedCacheKey, obj).then(function (res) {
resolve(res);
}).catch(function (err) {
reject(err, null);
});
is there any way for me to handle uncalled success event?
The primary issue here is that you're not providing a timeout argument to memcached.setAsync, but it's a mandatory argument for memcached.set. These two lines are equivalent:
memcached.set("foo", "bar", () => { /* this is never called */ });
memcached.setAsync("foo", "bar").then(() => { /* this is never called, either */ })
Add a timeout argument and your code should work as expected.

Why my test failed after adding didInsertElement to fetch json in ember?

I have a simple component that it's going to fetch data after the component is inserted. It was ok until I run my test. I got this error.
Assertion Failed: You have turned on testing mode, which disabled the run-loop's autorun. You will need to wrap any code with asynchronous side-effects in a run
I understand that the component is fetching data asynchronously but I'm not sure how to solve that in my integration test.
Here's my code
export default Ember.Component.extend({
didInsertElement: function() {
let source = this.get('source');
let url = apiUrl + source;
Ember.$.getJSON(url).then(function(response) {
this.set('data', response.data);
}.bind(this));
},
// something else
};
And this is my test.
moduleForComponent('panel', 'Integration | Component | panel', {
integration: true,
beforeEach () {
this.render(hbs`{{panel}}`);
}
});
test('it has source dropdown', function(assert) {
assert.equal(this.$('select[name="Source"]').length, 1);
});
Without the fetching data bit, the test runs ok.
Try wrapping the getJSON inside an Ember run loop.
So something like this:
var self = this;
Ember.run(function(){
Ember.$.getJSON(url).then(function(response) {
self.set('data', response.data);
});
});
Create a new Promise and then set the response data in the success handler.
The promise returned by Em.$.getJSON and new Ember.RSVP.Promise are different.
let self = this;
let promise = new Ember.RSVP.Promise(function() {
return Ember.$.getJSON(url);
});
promise.then((json) => {
this.set('data', json);
});

Can I act on and then forward the results of a AngularJS $http call without using $q?

I have functions like the getData function below.
I understand that $http returns a promise. In my current set up I am using $q so that I can do some processing of the results and then return another promise:
var getData = function (controller) {
var defer = $q.defer();
$http.get('/api/' + controller + '/GetData')
.success(function (data) {
var dataPlus = [{ id: 0, name: '*' }].concat(data);
defer.resolve({
data: data,
dataPlus: dataPlus
});
})
.error(function (error) {
defer.reject({
data: error
});
});
return defer.promise;
}
Is there any way that I can do this without needing to use the AngularJS $q (or any other $q implementation) or is the code above the only way to do this? Note that I am not looking for a solution where I pass in an onSuccess and an onError to the getData as parameters.
Thanks
As you say $http.get already returns a promise. One of the best things about promises is that they compose nicely. Adding more success, then, or done simply runs them sequentially.
var getData = function (controller) {
return $http.get('/api/' + controller + '/GetData')
.success(function (data) {
var dataPlus = [{ id: 0, name: '*' }].concat(data);
return {
data: data,
dataPlus: dataPlus
};
})
.error(function (error) {
return {
data: error
};
});
}
This means that using getData(controller).then(function (obj) { console.log(obj) });, will print the object returned by your success handler.
If you want you can keep composing it, adding more functionality. Lets say you want to always log results and errors.
var loggingGetData = getData(controller).then(function (obj) {
console.log(obj);
return obj;
}, function (err) {
console.log(err);
return err;
});
You can then use your logging getData like so:
loggingGetData(controller).then(function (obj) {
var data = obj.data;
var dataPlus = obj.dataPlus;
// do stuff with the results from the http request
});
If the $http request resolves, the result will first go through your initial success handler, and then through the logging one, finally ending up in the final function here.
If it does not resolve, it will go through the initial error handler to the error handler defined by loggingGetData and print to console. You could keep adding promises this way and build really advanced stuff.
You can try:
Using an interceptor which provides the response method. However I don't like it, as it moves the code handling the response to another place, making it harder to understand and debug the code.
Using $q would be the best in that case IMO.
Another (better ?) option is locally augmented transformResponse transformer for the $http.get() call, and just return the $http promise.

AngularJS : promises, can you pass a promise back after using .then()?

I'm still new to Angular and promises so I hope I have the correct idea here.
I currently have a data layer service which uses restangular to get some data, then returns a promise, like this...
dataStore.getUsers = function (params) {
return users.getList(params);
};
Then, my controller which has called this function receives a promise back, like this...
$dataStore.getUsers(params).then(function (response) {
$scope.users = response;
}, function(response) {
$log.error("Get users returned an error: ", response);
});
This is working well, but I'd like to use the promise inside of my datastore before passing it back. I'd like to use the .then() method to check if it failed and do some logging, then, from the sucess function and from the failure function I'd like to return the original promise back to my controller.
My controller would then be able to use the .then() method like it already is, in fact, I don't want my controller code to change at all, just my datastore code.
Here's some semi-pseudo code to show what I'd like my datastore function to do...
dataStore.getUsers = function (params) {
users.getList(params).then(function (response) {
$log("server responded")
return original promise;
}, function(response) {
$log.error("server did not respond");
return original promise;
});
};
You were actually not far off at all in your pseudo code. Promises chain:
dataStore.getUsers = function (params) {
return users.getList(params).then(function (response) {
$log("server responded")
return response;
}, function(failure) {
$log.error("server did not respond");
// change to throw if you want Angular lever logs
return $q.reject(failure);
});
};
The controller now gets resolved/rejected with the same value. The log requires tapping into the promise so you must add a .then handler to deal with it. Other promise libraries have convinicene methods for this but $q is minimalistic in this regard.
Alternatively, you can use nicer catch syntax, as well as propagate the errors to your logs:
dataStore.getUsers = function (params) {
return users.getList(params).then(function (response) {
$log("server responded")
return response;
}).catch(function(failure) {
$log.error("server did not respond");
throw failure;
});
};

Categories