I currently have a component that requires to have a pop up upon submit. The response from the API provides a redirectURL and redirectParams to be used as the popped up window.
Simply using window.open defaults its method to GET and not POST. This causes a Not Found page whenever it is loaded this way.
This is how I currently do it:
protected makeDepositPopup(depositRequest: PaymentRequest) {
this.depositService.requestDepositPopup(depositRequest)
.subscribe(
(depositEvent: RedirectData | SuccessfulDepositPopup) => this.handleDepositPopupEvent(depositEvent),
(error: EcommError) => this.handleDepositError(error),
() => this.eventService.depositAttempt.emit()
);
}
then the event is handled via the handleDeposit event:
protected handleDepositPopupEvent(depositEvent: RedirectData | SuccessfulDepositPopup) {
if (depositEvent instanceof RedirectData) {
this.handleRedirect(depositEvent);
} else {
this.handleDepositSuccessPopup(depositEvent, this.redirectParams);
}
}
As soon as it succeeds, it then tries to open a window with the corresponding URL and parameters provided by the API response:
protected handleDepositSuccessPopup(depositEvent: SuccessfulDepositPopup, redirectParams: string): void {
redirectParams = ""; // to remove undefined value
depositEvent.params.forEach(function (data, index) {
if(index == 0) {
redirectParams += "?" + data["key"] + "=" + data["value"];
} else {
redirectParams += "&" + data["key"] + "=" + data["value"];
}
});
window.open(depositEvent.url + redirectParams);
this.router.navigate(
["deposit", this.route.snapshot.data["instrumentTypeCode"], "deposit-details", depositEvent.id], {
relativeTo: this.route.parent.parent
});
}
How do I convert this in such a way that the depositEvent.url and its appended redirectParams to open a new window with a POST method to get a successful page response?
Related
I am working on one chrome extension and i need to use local storage to send data from options page to background scritps.
Options page script:
function addToStorage(key, val){
let obj = {};
obj[key] = val;
chrome.storage.local.set( obj, function() {
if(chrome.runtime.lastError) {
console.error(
"Error setting " + key + " to " + JSON.stringify(val) +
": " + chrome.runtime.lastError.message
);
}
});
}
Background:
chrome.storage.local.get('code', function(code) {
... with code.code ...
});
For example:
Now chrome.storage.local code value is abcd
I'm performing addToStorage('code', '1234') from options page script
After that in background script value code only will change when i manually click "update" at chrome extesions page
How can i automatically get actual data at background script?
the background script will check only once when started as is.
You could pass a mesage from the options script to background scripts after you update the local storage and use that as a trigger to check storage.
try this:
Options page
function addToStorage(key, val){
let obj = {};
obj[key] = val;
chrome.storage.local.set( obj, function() {
if(chrome.runtime.lastError) {
console.error(
"Error setting " + key + " to " + JSON.stringify(val) +
": " + chrome.runtime.lastError.message
);
}
chrome.runtime.sendMessage({status: "Storage Updated"}, function (responce) {
console.log(responce);
})
});
}
Background Page:
chrome.runtime.onMessage.addListener(
function (request, sender, responce) {
if (request.status === "Storage Updated") {
chrome.storage.local.get('code', function(code) {
// ... with code.code ...
});
sendResponce({status: "Update Recieved"});
}
}
);
Hope that helps, message passing docs here: https://developer.chrome.com/extensions/messaging
I am currently working on a mobile app with Nativescript. So, I do have a WebView in the main page to log in with Spotify. After the login I have to retrieve headers/queryparams from the page in the WebView. Is this possible and if, how do I do that?
You can register the loadFinishedEvent and check for the URL to get the queryparameters that are returning back to you. I am doing the same for third party login.
webViewLoaded(args) {
const webview: WebView = <WebView>args.object;
webview.on(WebView.loadFinishedEvent, (webargs: LoadEventData) => {
let message;
if (!webargs.error) {
if (webargs.url.toLowerCase().indexOf('spotity') > -1) {
//Read the parameters and navigate
}
message = 'WebView finished loading of ' + webargs.url;
} else {
message = 'Error loading ' + webargs.url + ': ' + webargs.error;
}
});
}
I have issue that have strange steps. I have ajax behave rendered on Head render stage
final AbstractDefaultAjaxBehavior behave = new AbstractDefaultAjaxBehavior() {
protected void respond(final AjaxRequestTarget target) {
boolean undoEn = getRequest().getQueryParameters().getParameterValue("undoEn").toBoolean();
if (undoEn) {
mSaveButton.setEnabled(true);
target.add(mSaveButton);
}
}
};
public String getCallbackName() {
return "saveButtonVisibilityToggle";
}
#Override
public void renderHead(IHeaderResponse response) {
String script = getCallbackName() + " = function (e) { Wicket.Ajax.ajax({\"u\": \"" + behave.getCallbackUrl() + " + &undoEn=\"+e+\"\" });}";
response.render(OnDomReadyHeaderItem.forScript(script));
}
Everything works well this behave called every time node changed in tinyMCE editor
settings.addCustomSetting(" setup: function(editor) {" +
" editor.on('NodeChange', function(e) {" +
" editor.save();" +
getCallbackName() + "(editor.undoManager.hasUndo())" +
" });" +
" }");
But sometimes when i leave browser tab, change few tabs (chrome) then use other app for few minutes, and turn back to our tab, ajax url have accidently appeared in browser url.
http://localhost:8080/wicket/bookmarkable/com.tac.kulik.pages.SomePage?3-1.IBehaviorListener.0-contentPanel&entityId=2+++&undoEn=true
this is also quite strange that instead normap parameter pass it's ++++ signs added
by the way this sighns recognized as "2 " so for some reason '+' changed to whitespace
UPDATE 1
Using #svenmeier answer i've page start's infinite loop refreshing. with logs
org.apache.wicket.core.request.mapper.StalePageException: A request to
page '[Page class = x.x.x.CardPage, id = 25, render count = 1]' has been
made with stale 'renderCount'. The page will be re-rendered.
and really for some reason behave link has renderCount 1, but form has 0.
the request from browser
jquery-1.12.4-ver-1476216952000.js:10254 XHR finished loading: GET "http://localhost:8080/wicket/bookmarkable/com.tac.pages.ca…?4-0.IBehaviorListener.0-contentPanel&cardId=1&_=1476873175645&undoEn=true"
I ve add some set of JS to prevent cicling refreshing, But i'we still has Stale exception
"if (editor.undoManager.hasUndo()) { " +
" console.debug('Behave called ');" +
behave.getCallbackScript() +
" }" +
this is my behave
final AbstractDefaultAjaxBehavior behave = new AbstractDefaultAjaxBehavior() {
protected void respond(final AjaxRequestTarget target) {
log.info("Behave called");
boolean undoEn = getRequest().getQueryParameters().getParameterValue("undoEn").toBoolean();
if (undoEn) {
mSaveButton.setEnabled(true);
target.add(mSaveButton);
}
}
//
#Override
protected void updateAjaxAttributes(AjaxRequestAttributes attributes) {
super.updateAjaxAttributes(attributes);
String undoEn = "return {'undoEn': editor.undoManager.hasUndo()};";
attributes.getDynamicExtraParameters().add(undoEn);
}
};
And there is no difference, it could be behave without any realization, page behaviour the same((
final AbstractDefaultAjaxBehavior behave = new AbstractDefaultAjaxBehavior() {
#Override
protected void respond(AjaxRequestTarget target) {
}
};
You should rework your behavior to use dynamic extra parameters instead.
#Override
protected void updateAjaxAttributes(AjaxRequestAttributes attributes)
{
super.updateAjaxAttributes(attributes);
String undoEn = "return {'undoEn': editor.undoManager.hasUndo()}";
attributes.getDynamicExtraParameters().add(undoEn);
}
And:
settings.addCustomSetting(
"setup: function(editor) {" +
" editor.on('NodeChange', function(e) {" +
" editor.save();" +
" " + getCallbackScript() + ";" +
" });" +
"}");
I seem to have a problem sending an alert (toast) message from a controller action using SignalR. Unless I add a Thread.Sleep() after the send call, I never see the message. Inevitably, the send call occurs before return View(), so I imagine the alert is visible for a millisecond on the previous view, until the new one is served.
My first, rough solution is to use a timer to keep sending the message, until I get an acknowledgement.
This solution stinks. What else can I do? I can have the 'receiving' pages poll the server to see if they have any alerts, but that defeats the purpose of SignalR.
But then, maybe SignalR isn't suited to my case and I should just send the alerts as json strings on the model.
From the Login action:
....
//ModelState.AddModelError("", "Invalid login attempt.");
AlertsHub.ShowClientAlert(new Alert(AlertLevel.Error, "Invalid login attempt."));
return View(model);
The hub:
public class AlertsHub : Hub
{
private static Alert pendingAlert;
static Timer pollTimer;
internal static void ShowClientAlert(Alert alert)
{
if (pendingAlert != null)
{
return;
}
pendingAlert = alert;
pollTimer = new Timer(_ => SendAlert(pendingAlert), null, 0, 500);
}
static private void SendAlert(Alert alert)
{
IHubContext context = GlobalHost.ConnectionManager.GetHubContext<AlertsHub>();
context.Clients.All.ShowAlert(alert.Level.ToString(), alert.Message, alert.Title);
}
[HubMethodName("AlertReceived")]
public void AlertReceived(Guid alertId)
{
pollTimer.Dispose();
pendingAlert = null;
}
}
From the JS:
var toast;
$(function () {
if (typeof toast != 'undefined' && toast != null) {
showToast(toast);
toast = null;
}
var alertsProxy = $.connection.alertsHub;
alertsProxy.client.showAlert = function(alertId, level, message, title) {
toast.alertId = alertId;
toast.level = level;
toast.message = message;
toast.title = title;
};
$.connection.hub.start()
.done(function () {
console.log('Now connected, connection ID=' + $.connection.hub.id);
})
.fail(function () {
console.log('Could not Connect!');
});
});
function showToast(toast) {
switch (toast.level.toLowerCase()) {
case "success":
toastr.success(toast.message, toast.title);
break;
...
}
alertsProxy.server.AlertReceived(alertId)
.done(function() {
console.log("Alert '" + alertId + "' acknowledged.");
})
.fail(function() {
console.log("Acknowledgement of alert '" + alertId + "' failed.");
});
}
In my app, I have two types of profile for organisations. When a user click on a profile name, I first need to check whether I have a premium profile for that organisation, and if so, route the user in that direction. If there is no premium profile, the user is sent to the standard profile.
I'm doing this using ng-click, which send id and a resource (in this case, organisation) parameters to a controller, where the conditions are evaluated and then the user is routed in the correct direction. All of this works correctly when a user clicks as normal.
However, when a user tries to open the link in a new tab, by right clicking and selecting that option, the new tab opens with the url of the current page. So the ng-click and controller has not fired or evaluated the request before opening the new tab.
How can I change by code so that Angular processes the ng-click request before opening the new tab? Or more broadly, how can I allow my users to open one of these links in a new tab so that they are not just displayed the page they are currently on?
HTML
<div ng-controller="ProfileRouter">
<div ng-repeat="org in orgs | orderBy:'org.name'">
{{ org.name }}
</div>
</div>
Inside ProfileRouter controller
$scope.profileCheck = function (id, resource) {
$http({method: 'GET', url:'/IdCheck', params:{'id': id})
.success(function(data) {
var count = data.hits.found;
if (count) {
var hash = data.hits.hit[0].id;
}
if (resource == 'organisation') {
theResource = 'universities';
page = 'overview';
}
if (count == 1) {
window.location.href = "/" + theResource + "/profile/" + hash + "/" + page;
}
if (count == 0) {
window.location.href = "/" + resource + "/" + id;
}
})
.error(function(data) {
$scope.data = data || "Can't get resource";
});
}
I know this is an old question. But I found out a solution to this & posting it here might help someone else.
First of all I have created a custom directive for right click:
module.directive('tabRightClick',['$parse', function($parse) {
return function(scope, element, attrs) {
var fn = $parse(attrs.tabRightClick);
element.bind('contextmenu', function(event) {
scope.$apply(function() {
// event.preventDefault();
fn(scope, {$event:event});
});
});
};
}]);
Then applied this directive as an attribute in the HTML file and call the same method that is being called on ng-click:
<div ng-controller="ProfileRouter">
<div ng-repeat="org in orgs | orderBy:'org.name'">
{{ org.name }}
</div>
</div>
Here locationPath is a $scope bound variable, which we need to implement in the controller.
Its value should be updated in the profileCheck function based on the various conditions.
$scope.profileCheck = function (id, resource) {
$http({method: 'GET', url:'/IdCheck', params:{'id': id})
.success(function(data) {
var count = data.hits.found;
if (count) {
var hash = data.hits.hit[0].id;
}
if (resource == 'organisation') {
theResource = 'universities';
page = 'overview';
}
if (count == 1) {
window.location.href = "/" + theResource + "/profile/" + hash + "/" + page;
$scope.locationPath = "/" + theResource + "/profile/" + hash + "/" + page;
}
if (count == 0) {
window.location.href = "/" + resource + "/" + id;
$scope.locationPath = "/" + resource + "/" + id;
}
})
.error(function(data) {
$scope.data = data || "Can't get resource";
});
}
Hope it's helpful.