ipcMain help needed - electron

I am trying to send a reply message back to my render. In the render I get a print out of "undefined" in the console log. I am trying to get the json response back from my api call
So far I tried the follow
ipcMain.on("get_scenes", (event, arg) => {
axios.get("http://localhost:60704/getMovies").then(function (response) {
// handle success
console.log("my message", response);
});
event.returnValue = response;
});
and
ipcMain.on("get_scenes", (event, arg) => {
axios.get("http://localhost:60704/getMovies").then(function (response) {
// handle success
console.log("my message", response);
event.returnValue = response;
});
});

The problem in example #1 is that the response variable can't be gotten from outside the function it's declared in.
The problem in example #2 is that axios.get( is asynchronous which means it doesn't get the response instantly like a synchronous function would. This means that event.returnValue would be set too late and the response wouldn't work.
The solution is to reply with a new message like this:
ipcMain.on("get_scenes", (event, arg) => {
axios.get("http://localhost:60704/getMovies").then(function (response) {
event.sender.send('scenes_response', response);
});
});
Then recieve it in the renderer like this:
var ipcRenderer = require('electron').ipcRenderer;
ipcRenderer.on('scenes_response', function (evt, messageObj) {
// messageObj Now contains the response.
console.log(messageObj);
});

try win.webContetens.send instead of event.sender.send
like this,
ipcMain.on("get_scenes", (event, arg) => {
axios.get("http://localhost:60704/getMovies").then(function (response) {
win.webContents.send('scenes_response', response);
});
});

Related

Using ipcRenderer with contextBridge

I want use contextBridge in my preload.js in electron. Every work as usual when when i send data from the ipcrender-to-ipcmain, but problem arises when i send response from ipcmain-to-ipcrenderer. I have gone through some of there solutions here but i still get the same results.
This is my mainjs code
ipcMain.on('users:load', async function () {
const users = await User.getAll();
win.webContents.send('users:get', users);
});
(async function () {
try {
const rows = await User.getAll();
console.log(rows.length);
win.webContents.send('users:total', rows.length);
} catch (error) {
return console.log(error);
}
})();
This is my preload.js
contextBridge.exposeInMainWorld('UserApi', {
loginuser: (user) => ipcRenderer.invoke('user:login', user),
totalusers: () =>
ipcRenderer.on('user:total', (e, res) => {
return res;
}),
loadUsers: () => {
ipcRenderer.send('users:load', () => {
ipcRenderer.on('users:get', (e, users) => {
return users;
});
});
},
});
In my preload.js ipcRenderer.invoke works perfectly but ipcRenderer.on does not. Any help will be appreciated.

<function> is not defined at HTMLButtonElement.onclick

Good day,
I have a button
<button id="4" onclick="UpdateStatus(this.id)" class="btn btn-default" type="button">update</button>
that is calling an ajax function
<script>
$(document).ready(function () {
function UpdateStatus(Id) {
$.ajax({
type: "Post",//or POST
url: '/myController/UpdateSomething?Id=' + Id,
// (or whatever your url is)
data: { data1: var1 },
success: function (responsedata) {
// process on data
alert("got response as " + "'" + responsedata + "'");
}
});
}
}
</script>
My problem is that I receive an error in my view:
UpdateStatus is not defined at HTMLButtonElement.onclick
what am I doing wrong? thanks
Update
When I try to run this code
#section scripts
{
<script>
$(document).ready(function () {
//Carga datos del curso
console.log("asdf");
});</script>}
I do not get the message in my console.
The problem is, You are defining your method definition inside the document.ready event of jQuery. When the button markup was parsed and rendered, the JavaScript method was not defined, hence you are getting the error.
The jquery ready method gets executed a little later when the document is ready (parsing and rendering of the HTML is already done, DOM is safe to be accessed). By this point, the HTML has been already rendered.
Define it outside it.
<script>
function UpdateStatus(Id) {
alert('UpdateStatus called');
}
$(function () {
});
</script>
Another option is to use unobutrusive JavaScript. So instead of wiring up a click event handler to the button markup, you will wire up later, when document ready is fired.
<button id="4" class="btn btn-default" type="button">update</button>
and wire up the click event
$(function () {
$("#4").click(function (e) {
e.preventDefault();
alert('User clicked');
});
});
<script>
function F(user_id) {
var user_id = user_id;
$.ajax({
type:"GET",
url:"http://127.0.0.1:8000/preference",
data: {'user_id':user_id},
async: false,
success: function (result) {
console.log(result)
}
});
}
</script>
the first line is automatically not to display. It is the script's type and src attributes. I used the "text/javascript" and "http://code.jquery.com/jquery-latest.js".
This question I found 2 solutions. One is as the above. To divide the script into two parts. Second is to move the function to under the button tag.
It is really a scope question. But I didn't find the solution's logic. But I solve it.
This is definitely a scoping issue, because UpdateStatus defined within the scope of document.ready() function. You can declare UpdateStatus as variable outside document.ready() block and declare a function inside it:
var UpdateStatus;
$(document).ready(function () {
UpdateStatus = function () {
var buttonId = $('#4').attr('id');
$.ajax({
type: "POST",
url: '/myController/UpdateSomething',
data: { Id: buttonId, ... }, // setting parameters
success: function (responsedata) {
// process on data
alert("got response as '" + responsedata + "'");
}
});
}
});
Additionally, based from standard event registration model and separation of concerns, I suggest you to use unobtrusive JavaScript by retrieving button ID like this:
$(document).ready(function () {
$('#4').click(function() {
var buttonId = $(this).attr('id');
$.ajax({
type: "POST",
url: '/myController/UpdateSomething',
data: { Id: buttonId, ... }, // setting parameters
success: function (responsedata) {
// process on data
alert("got response as '" + responsedata + "'");
}
});
});
});
Because you're using AJAX POST, no need to use query string parameters in URL like url: '/myController/UpdateSomething?Id=' + Id.
Related issues:
Uncaught ReferenceError: (function) is not defined at HTMLButtonElement.onclick
Why is inline event handler attributes a bad idea in modern semantic HTML?

Ajax call will not work without preventDefault

In an MVC page, I have the following jQuery/javascript:
$("form").submit(function (event) {
var inp = $("input"); inp.attr('value', inp.val());
var html = replaceAll(replaceAll($('html')[0].outerHTML, "<", "<"), ">", "<");
// event.preventDefault();
$.ajax({
url: "/Ajax/SetSession",
asynch: false,
dataType: "json",
cache: false,
type: "get",
data: { name: 'html', data: html.substring(0, 1024) },
error: function (xhr, status, error) {
alert("Ouch! " + xhr.responseText);
// $(this).unbind('submit').submit();
},
success: function (data) {
alert("Awesome: " + data);
// $(this).unbind('submit').submit();
},
complete: function (xhr, status) {
alert('Phew!');
$(this).unbind('submit').submit();
}
});
});
It is meant to intercept the normal submit process, capture the html of the page before it's submitted, and then continue on its way as if nothing happened.
But the problem is, with both commented out, the form re-submits, as expected, put the controller never executes the /Ajax/SetSession url. Whereas, if I uncomment them, the /Ajax/SetSession does execute but the unbind does not appear to work as the form does not seem to get resubmitted.
Not sure what's going on here. What am I missing?
Any and all clues appreciated.
event.preventDefault(); should stay uncommented since this prevents form to submit instantly. Apparently you want to control the moment at which form is submitted.
$(this).unbind does not work because inside success and error handles context is no longer form - it is an jQuery ajax context object. You can do two things here to have the behavior you want:
Set context explicitly to be the form object. This can be done via context property:
$.ajax({
...
context: this, //form here!
...
success: function (data) {
alert("Awesome: " + data);
$(this).unbind('submit').submit(); //now this refers to form
},
Refer to form using a different variable:
$("form").submit(function (event) {
var form = this;
...
$.ajax({
...
success: function (data) {
alert("Awesome: " + data);
$(form).unbind('submit').submit(); //using form variable instead of this
},

.toHaveBeenCalled() true when should be false

When I run the following test, it passes. It is supposed to fail (note the commented line making the tap() call). It is only supposed to pass when the tap() call is made. Would anyone have any idea why $.mobile.loading is showing as having been called when I don't send a tap() event?
beforeEach(function() {
jasmine.getFixtures().fixturesPath = ".";
loadFixtures('index.html');
});
/* this test is buggy - it passes even when the tap() method is not called */
it("should display a PageLoadingMsg", function() {
var PageLoadingMsgCount = 0;
runs(function() {
$('#account_creation').trigger('pageinit');
console.log('d');
spyOn($.mobile, 'loading').andCallFake(function() {
PageLoadingMsgCount++;
console.log('a');
});
console.log('e');
spyOn($.mobile, 'hidePageLoadingMsg');
spyOn($.mobile, 'changePage');
});
runs(function() {
expect($('#account_creation_create_account_button')).toHaveAttr('data-role','button');
// $('#account_creation_create_account_button').tap();
});
waitsFor(function() {
return (PageLoadingMsgCount > 0);
}, "PageLoadingMsgShown timed out", 1000);
runs(function() {
expect($.mobile.loading).toHaveBeenCalled();
console.log(PageLoadingMsgCount);
expect(PageLoadingMsgCount).toBeGreaterThan(0);
});
});
Here is the call it is trying to spy on:
$(document).on('pageinit', '#account_creation', function(event) {
$(document).on('tap', '#account_creation_create_account_button', function(event) {
event.stopImmediatePropagation();
event.preventDefault();
console.log('b');
$.mobile.loading('show', {theme:settings['theme'], text:"Creating account..."});
console.log('c');
...
Thanks,
David
I just ended up waiting for the call count to get to 2.
waitsFor(function() {
return (PageLoadingMsgCount > 1);
}, "PageLoadingMsgShown timed out", 1000);

Asp.net Mvc jquery ajax?

I have links like following.
Deneme Müşteri 2
Deneme Müşteri 2
I want to use jquery ajax post like this:
$(".customer_details").click(function () {
$.ajax({
url: $(this).attr("href"),
type: 'POST',
beforeSend: function () {
},
complete: function () {
},
success: function (result) {
$("#customer_operations_container").html(result);
},
error: function (result) {
alert("Hata!");
}
}); //end ajax
});
Or this:
$(".customer_details").click(function () {
$("#customer_operations_container").load($(this).attr("href"));
});
And Action Method
public ActionResult _EditCustomer(int CustomerId)
{
// get customer from db by customer id.
return PartialView(customer);
}
But I cant do what I wanted. When I click to link, PartialView does not load. It is opening as a new page without its parent. I tried prevent.Default but result is the same.
How can I load the partialView to into a div?
Note: If I use link like this <a href="#"> it works.
Thanks.
Maybe the problem is with the actionresult, try with Content to see if that changes anything.
public ActionResult _EditCustomer(int CustomerId)
{
// get customer from db by customer id.
return Content(customer.ToString());
}
Try one of these...
$(".customer_details").click(function (e) {
e.preventDefault()
$.ajax({
url: $(this).attr("href"),
//I think you want a GET here? Right?
type: 'GET',
beforeSend: function () {
},
complete: function () {
},
success: function (result) {
$("#customer_operations_container").html(result);
},
error: function (result) {
alert("Hata!");
}
}); //end ajax
});
Or
$(".customer_details").click(function (e) {
e.preventDefault();
$("#customer_operations_container").load($(this).attr("href"));
});
Or
$(".customer_details").click(function (e) {
e.preventDefault();
$.get($(this).attr("href"), function(data) {
$("#customer_operations_container").html(data);
});
});
If none of this works, check if there's any js errors
The problem is when you click on the link you already start navigation to it. So just use e.preventDefault() or return false from the click method to prevent the default behavior
$(".customer_details").click(function (e) {
e.preventDefault();
...
}
This should help you out:
$.ajax({
url: $(this).attr("href"),
type: 'POST',
beforeSend: function () {
},
complete: function () {
},
success: function (result) {
$("#customer_operations_container").html(result);
},
error: function (result) {
alert("Hata!");
}
}); //end ajax
return false;
The only thing you where missing is the prevention of A tag working. By returning false your custom event is called and the default event is not executed.
Try this
$(function(){
$(".customer_details").click(function (e) {
e.preventDefault();
});
});
Using ready event
Demo: http://jsfiddle.net/hdqDZ/

Resources