FB.ui() giving error in Safari with asynchronous request when user is not already logged in - asynchronous

I'm trying to get have users be able to post to their Facebook walls on my external site.
I've encountered a problem in Safari. If the user isn't logged in, i.e. they have not gone through the flow that calls FB.login(), I get the following JS error when calling FB.ui():
TypeError: 'undefined' is not an object (evaluating 'b.fbCallID=a.id')
However, if they are logged in, the dialog appears just fine.
FB.ui() is called in a callback function -- I'm retrieving a unique url from my server, and then calling FB.ui(). If I call FB.ui() directly, it works fine, but not when it's asynchronous.
Here's the code:
retrieveUrl(param1, param2, function(result) {
FB.ui({ method: 'feed',
description: 'My Description',
display: 'dialog',
link: result.uniqueUrl,
picture: 'http://foo.com/bar.jpg'
}, function(response) {
if (response && response.post_id) {
//Posted message
} else {
//Not posted message
}
});
});
This works in other browsers, regardless of logged in state or not.

FB.login or FB.ui methods must be called on a user initiated action (click) in Safari for new window/popup/iframe to be rendered by FB.UIServer.
If you try calling these methods on a network callback event it will be blocked and the exception you described will occur:
TypeError: 'undefined' is not an object (evaluating 'b.fbCallID=a.id')
Can you retrieve the unique URL before the user interacts with the page and then present the feed dialog when they click on a button?

Related

Halt progress of Ninja Forms if Webhooks respond with error

I'm setting up Ninja Forms in Wordpress. And I want to use the Webhooks extension to post a code to an external URL. If the code is correct Ninja Forms should submit the data on move on. If the code is wrong then the user should get an error message and try again.
How can I do this, I see no way if interrupting the submit?
In Ninja Form when you use webhook, I guess you may catch the error respond from the API with this code
$data['errors']['form'][] = $this->submit_response->result[0]->error;
So when the API respond error, in this case user has no chance to re-submit the form again unless reload the page.
When the form contain the error, Ninja form prevent the form to submit, so you need to find a way to clear/remove this error.
Few workarounds can fix this problem.
An easy way is that, you cache the respond error differently with the following code:
$data['errors']['last']['message'] = $this->submit_response->result[0]->error;
With this code, your form will not display the error message respond from API but it is possible for user to re-submit the form again and you can use the javascript code below to display the error to some HTML element
var customFormController = Marionette.Object.extend({
initialize: function() {
// Listen to submit respond
this.listenTo(nfRadio.channel( 'forms' ), 'submit:response', this.checkSubmitRespond);
},
checkSubmitRespond: function(response, textStatus, jqXHR, formID) {
if ('undefined' != typeof response.errors.last) {
var msg = response.errors.last.message;
// display error on some pre-defined element
jQuery('.error-container').html(msg);
}
}
});
jQuery(document).ready(function($) {
new customFormController();
});
Hope this help.

Why Meteor.user and Meteor.userId differ?

I have an interceptor:
Router.onBeforeAction(function() {
if (!Meteor.userId()) {
console.log("lets login");
Router.go("login");
} else {
this.next();
}
}, {
except: ['login', 'signup']
});
It works very well, until I replace the !Meteor.userId() for Meteor.user(). It seems that .user when refreshing the page goes undefined and redirect it to my login page. My login router also verifies .user and here it is right.
Why this difference?
That's true, Meteor.userId() returns the id while Meteor.user() returns the object.
However, returning an object (Meteor.user()) takes more time than just returning an ID, due to the asynchronous issue, by the time the script is checking if (!Meteor.user()) {...}, Meteor.user() has not been processed and returned yet!
As a result, there are several ways to due with that asynchronous issue (for example, in Meteor/React application, we may have something like subscribe, and wait until the handle is ready)

Meteor: Resend email verification link

I want to be able to resend an email verification link to users of my Meteor application in case they accidentally delete their email verification email.
I have a link with the id "resentEmailVerificationLink"
I have the following code in my client for when the link is click (alerts are just there to show myself how far the function gets before an error):
Template.dashboard.events({
'click #resentEmailVerificationLink' : function(event) {
event.preventDefault();
var id = Meteor.userId();
alert('clicked: ' + id);
Accounts.sendVerificationEmail(id);
alert('Verification Email resent');
return false; // Stops page from reloading
}
)};
I know the sendVerificationEmail is a server function but I have no idea how to call this function in the server upon clicking the verify email link (I'm a bit of a Meteor newbie).
Any idea of how to accomplish this, because currently it doesn't work with the following error: Uncaught TypeError: Accounts.sendVerificationEmail is not a function
Note: Meteor.Accounts.sendVerificationEmail(id); doesn't work either (it does however produce a different error.
You can try with server side method just create one pass the attrs and call http://docs.meteor.com/#/full/accounts_sendverificationemail on the server. More about meteor methods: http://docs.meteor.com/#/full/meteor_methods

Can't authenticate using email and password

I'm trying to authenticate a user with a custom login form. I designed the form, and I'm trying to authenticate users like this:
Template['account.login'].events
'submit #login-form': (e, t) ->
e.preventDefault()
Meteor.loginWithPassword(
t.find('#login_username').value,
t.find('#login_password').value,
(err)->
console.log(err)
)
return false
Relevant Template(in JADE - sorry):
form.smart-form.client-form#login-form(novalidate)
fieldset
section
label.input
input#login_username(type="text", name="username")
section
label.input
input#login_password(type="password", name="password")
footer
button.btn.btn-primary(type="submit", id="login.btn.login") Login
From the resource I found online, this would be correct. However, I get this exception thrown on the server:
Exception while invoking method 'login' Error: Match error: Failed Match.Where validation in field username in field user.username
You forgot to add a tab and Meteor.loginWithPassword() is running outside the Template event. Paste your coffeescript code at http://js2.coffee/ and you'll see it right away.

"Login Forbidden" when using Meteor's Accounts.validateLoginAttempt(func)

I have a basic Meteor method that I am trying to call whenever the user attempts to sign in.
Accounts.validateLoginAttempt(function (options) {
Meteor.call('method', true, function (error, result) {
// do nothing
});
});
However, whenever I try to sign in, I receive "Login Forbidden" as an error. The same happens upon sign up. I am guessing I need to be returning something for the function, but do not know what. Your help would be greatly appreciated!
From the docs http://docs.meteor.com/#/full/accounts_validateloginattempt
A validate login callback must return a truthy value for the login to proceed. 
In the block do some validations like if user is verified or not and return true or false to complete the login process.

Resources