Account.createUser call back is not working in meteorjs - javascript

I am developing an app with meteor js. I have created one meteor method for creating user. It's showing me following error:-
Accounts.createUser with callback not supported on the server yet.
here is my meteor method
how can i add callback in account.createUser?
Meteor.startup(function () {
Meteor.methods({
postForm:function(doc){
var result = Accounts.createUser({
username: doc.username,
password: doc.password,
email: doc.emails,
profile: {
lastname: doc.lastname,
contact:doc.phoneNumber,
bdat:doc.bod,
address:doc.address
}
},function(){
console.log('hello');
});
}
});
});

The "yet" in that error message is likely a mistake on the author's part. According to the documentation:
On the server, [Accounts.createUser] returns the newly created user id.
This means that on the server-side, Accounts.createUser is essentially blocking: it waits for the user to be created, and then returns its newly generated id. So "the callback", in that case, is basically anything that follows your createUser statement. You get one value, the user's _id, which you can use to retrieve the inserted user with Meteor.users.find(). And you can catch thrown exceptions if you want to cover errors.
But as David Weldon said, you could basically do that using Accounts.createUser() on the client, which takes a callback. I guess it makes sense if you want to do something server-specific in the "callback" of that creation, but one may also argue that you could do a server method call just for that. (though it would call the server twice in that case, once for the creation, and once for the callback logic)

I received exactly the same error message including the word "yet." My complete error message: Exception while invoking method Error: Accounts.createUser with callback not supported on the server yet. Translate that error message as
Hey, Developer, you big dummy, your method call doesn't handle both
response and error via callbacks, yet. Please fix your code.
The issue for me was two fold. Like you, I did not adequately account for callback error and response. What that means is, if there is an error somewhere else in the chain of calls, that error WON'T get passed back to you, so you have no idea what's wrong. Fix the call back code first.
Meteor.methods({
postForm:function(doc){
try {
var result = Accounts.createUser({
username: doc.username,
password: doc.password,
email: doc.emails,
profile: {
lastname: doc.lastname,
contact:doc.phoneNumber,
bdat:doc.bod,
address:doc.address
}
});
if(result){
// are you using roles?
// Roles.addUsersToRoles(result, doc.roles);
return result;
}
}
catch(err){
return err;
}
}
});
Hopefully this will 'fix' the callback not supported error message. And at that time you should be able to see what is really causing your troubles. In my case it was a faulty Accounts.validateNewUser((user) routine that I had copied from a tutorial and forgotten to update to match my data.
Oh, almost forgot... here's sample code to call the method from the client.
Meteor.call('postForm', newUser, function(error, response) {
if (error) {
console.log('postForm: Error: ', error);
}
if (response) {
console.log('postForm: Response: ', response);
}
});
Good luck with this. Info offered here in case anybody gets the "yet" error!

Related

SignalR error when invoking method on the server from JavaScript client

I have a C# server running my hub class, which contains only 1 method in there, which is as follows,
public class HothHub : Hub
{
public async Task AddSingleUserGroup(string name)
{
await Groups.AddToGroupAsync(Context.ConnectionId, name);
}
}
I also have a JavaScript client, which connects to the hub via the following code,
var connection;
async function signalRStart() {
connection = new signalR.HubConnectionBuilder()
.withUrl("https://somesignalrurl.com/hothhub", { withCredentials: false })
.withAutomaticReconnect()
.configureLogging(signalR.LogLevel.Information)
.build();
connection.on("hothHubToHothUpdate", () => {
console.log("Called by the server!");
});
connection.onreconnecting(error => {
console.log("Connection lost due to error " + error + ". Reconnecting.");
});
// Start the connection.
await start();
}
async function start() {
try {
await connection.start();
connection.invoke("addSingleUserGroup", "someUniqueUserName");
} catch (err) {
console.log(err);
setTimeout(start, 5000);
}
};
Now when the client initiates the connections and run start() on itself, this part seems to run fine. A connection to the signalR hub is made successfully. The problem I'm having is when connection.invoke("addSingleUserGroup", "someUniqueUserName"); is run although the error does not happen all the time. On first run, the method at the server end is hit successfully however, it looks like subsequent calls to it fail and this is the error returned in the client,
Uncaught (in promise) Error: Failed to invoke 'addSingleUserGroup' due to an error on the server. HubException: Method does not exist.
at _callbacks.<computed> (signalr.js:1252:36)
at HubConnection._processIncomingData (signalr.js:1364:33)
at HubConnection.connection.onreceive (signalr.js:985:52)
at webSocket.onmessage (signalr.js:2236:30)
I've read a few articles on here but most seemed to be related to the client calling the wrong method name having used a capital letter at the start of the method name when invoking it and some having mentioned issues with the method expecting 1 type parameter and receiving another type although in my instance here its hard to think how the server would not treat the incoming parameter as a string, which is what is being passed in. Has anyone got any ideas on what could be wrong here or what I could try?
Thanks!
Unfortunately I dont have an actual answer for this but after deploying the solution to my Azure App Service, the release version does not produce the error. It seems the error only persisted when in debug mode but like I said I'am not sure why.

Clarifying "400 - Bad Request"

I am triggering a bad request on purpose from my backend. The backend using express is answering properly as expected with:
[...]
.catch((error) => {
res.statusCode = 400;
res.json({
msg: "This is some error",
err: error,
});
});
My question is: Is the 400 always showing up in browser console? I thought I handled the error the right way.
And why do I have to retrieve the data in the frontend with
// 400:
function (data) {
var data = data.responseJSON.msg);
}
instead of (similar to 200:)
// 400:
function (data) {
var data = data.msg);
}
I am just wondering, if I do something wrong.
Thanks for any advice
When fetching data asynchronously, any response other than a 2** response code gets handled by a .catch block. So any other response whether it be 4** or 5** gets caught by the catch block and for that reason if you're using a library like Axios or the likes the response from the backend will be in the error.response or data.response in your case.
I wasn't aware of what you're using to carry out the asynchronous fetching of data i.e. Fetch Api so my answer is a generic response and also is the above code complete?
In my experience any error from whatever weither it be am asynchronous call that generates an error always gets logged to the console, but you can from the front end handle those errors in the catch block
The problem is when the console.log tries to output the error, the string representation is printed, not the object structure, so you do not see the .response property or in your case the .responseJSON
By catching your error with an catch block .catch() or if you using async / await you should, usually, wrap the code inside of an try / catch to catch the error otherwise it will always output this red error in the console

How to handle can-connect errors correcly when connecting to a RESTful API

I've managed to load data and to save data. But cannot understand the error handling scheme needed.
When everything goes fine I receive the same object in that was sent but with an extra attribute _saving (false).
When something goes wrong, for instance try to store a string instead of a number, I'll get:
Bad request (error on the console, don't want that)
The response object (might be usefull to show an error)
"Uncaught (in promise)" error
Example:
Code:
this.save()
.then(function(result) {
console.log('ok1', result);
}).catch(function() {
console.log('errorHandler1');
});
OK:
Error:
I've been trying to use catch on promises, following this guidelines:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/catch
but had no luck at all.
This should should work buy just changing p1.then to thisObjectThatIWantToSave.save.then but it didn't.
p1.then(function(value) {
console.log(value); // "Success!"
throw 'oh, no!';
}).catch(function(e) {
console.log(e); // "oh, no!"
}).then(function(){
console.log('after a catch the chain is restored');
}, function () {
console.log('Not fired due to the catch');
});
Again, it still stores the information when the data is correct, the problem I see is that I don't have the tools to decide when was the data correctly stored or not and to avoid triggering errors that can be correctly handled.
I'm using
canjs v3.0.0-pre.11
a restful API provided by feathers
Regarding the error handling ...
Bad request (error on the console, don't want that)
There's no way of preventing the error on the console. This is something chrome does.
The response object (might be usefull to show an error)
You can read the reason for the rejection in can-stache like {{promise.reason}}.
"Uncaught (in promise)" error
I'm not sure why this is being thrown as clearly, your catch is being hit. If you change it to:
this.save()
.then(function(result) {
console.log('ok1', result);
},function() {
console.log('errorHandler1');
});
Do you get the same behavior?

cannot understand what callback does in a Connect module

I am reading a book about NodeJs Connect. There is this small part about basicAuth module. I know that basicAuth is now deprecated, but I cannot understand this simple code. The book says
Providing an asynchronous callback function
The final option is similar, except this time a callback is passed to
basicAuth() with three arguments defined, which enables the use of
asynchronous lookups. This is useful when authenticating from a file
on disk, or when querying from a database.
Listing 7.7. A Connect basicAuth middleware component doing
asynchronous lookups
And no other information. Thats the whole part about having a callback in the basicAuth
So, code gets the username and the password. Then hypothetical object User has a method authendicate that checks if this user actually exists. And when its finished, calls the gotUser function. gotUser contains either a returned error (=no user found with that username/password) or a returned user object (a user found with that username/password). Am I right?
gotUser checks if there is an error. If there is, returns and calls callback with an error argument. So wait, what will callback do at this point? Its not defined anywhere. Will it pass the error to an error handler function? And how?
If there is not an error, gotUser calls callback again with null(= no error) and user. Once again, what will callback do? Why pass the returned user to the callback and not grab its name, mail, age etc etc and use them on a session or fill the innerHTML of a tag or whatever?
Thanks
So wait, what will callback do at this point? Its not defined anywhere.
The value of callback is defined by the basicAuth middleware.
You can find its definition within the basic-auth-connect module, used by connect, in the module's index.js:
callback(user, pass, function(err, user){
if (err || !user) return unauthorized(res, realm);
req.user = req.remoteUser = user;
next();
});
When gotUser() invokes callback(...), it's call the function(err, user){...} from the above snippet, passing the err and/or user along to be used.
And, how they're used, in the two scenarios you were wondering about...
gotUser checks if there is an error. If there is, returns and calls callback with an error argument. So wait, what will callback do at this point?
If there is not an error, gotUser calls callback again with null(= no error) and user. Once again, what will callback do?
The if (err || !user) condition will pass for both (one has an error, the other is lacking a user). It then considers the request unauthorized and will end the response immediately.
function unauthorized(res, realm) {
res.statusCode = 401;
res.setHeader('WWW-Authenticate', 'Basic realm="' + realm + '"');
res.end('Unauthorized');
};
Why pass the returned user to the callback and not grab its name, mail, age etc etc and use them on a session or fill the innerHTML of a tag or whatever?
The middleware is applying separation of concerns, keeping itself as small and concise as possible. It's goal is just to determine a req.user and validate it.
When it's done that successfully, other middleware in the application's queue will be able to reference the user that was found. This can includes using it to render markup from a view:
// determine the user
app.use(connect.basicAuth(...));
// now make use of it
app.use(function (req, res, next) {
viewEngine.render('view', { user: req.user }, function (err, result) {
if (err) return next(err);
res.setHeader('Content-Type', 'text/html');
res.end(result);
});
});
Note: This is generalized and won't run as-is. You'll need to find and setup a view engine of your choice and substitute that into the snippet.
Also, side note on...
fill the innerHTML of a tag
Though Node.js is executing JavaScript, it's doing so within its own environment, completely detached from any browsers. It's not possible to interact directly with the DOM currently seen by the user.
There are a couple of different things going on. For one, app.use expect a function that will be called with req, res, and next. When you run connect.basicAuth, it runs this method.
Since this is a middleware method, this method will run every time a route that was defined after this method is hit.
The second thing that is going on is connect.basicAuth is a function that will be called with username, password, and a callback method. Callback is something that connect.basicAuth provides.
If you return callback(err), it will send a 401 Not Authorized back to the client. If you return callback(null, user), it will continue until either the next middleware function, or the appropriate route.

Parse custom webhook: can I query my tables?

In a Parse custom webhook, which is of the form:
app.post('/receiveSMS', function(req, res) {
Where receiveSMS is hooked up to the Twilio api and this method is properly called (I have logs to prove it), but I'm trying to query on my tables within this method and it doesn't seem to be working.
Is this allowed, or is there anything special I need to do to make this work?
var contactObj = Parse.Object.extend("Contact");
var contactQuery = new Parse.Query(contactObj);
console.log(req.body.From);
contactQuery.each(function(contact) {
and the body of the each call never gets called.
Is this allowed, and if so, what am I doing wrong here?
Update -- The entirety of the webhook code block is:
app.post('/receiveSMS', function(req, res) {
console.log('receive SMS');
console.log(req.body.Body);
res.send('Success');
if(req.body.Body.toLowerCase() == "in" || req.body.Body.toLowerCase() == "out") {
twilio.sendSMS({
From: "(xxx) xxx-xxxx",
To: req.body.From,
Body: "It's been noted, and notifications have been sent. Check us out!"
}, {
success: function(httpResponse) {
console.log(httpResponse);
response.success("SMS Sent!");
},
error: function(httpResponse) {
console.error(httpResponse);
response.error("Uh OH, something went wrong");
}
});
if(req.body.Body.toLowerCase() == "in") {
console.log("in was received");
// eventQuery
var contactObj = Parse.Object.extend("Contact");
var contactQuery = new Parse.Query(contactObj);
console.log(req.body.From);
// contactQuery.equalTo("phone", req.body.From);
contactQuery.first({
success: function(contact) {
console.log("found contact");
console.log(contact);
}, error: function(error) {
alert("Error: " + error.code + " " + error.message);
}
});
}
}
});
This code is called and the logs "console.log('receive SMS')" and the like are all called, except for what is inside the query's first call.
Queries on tables is fine, but you can't use the each() function, as that is restricted to only work in background jobs.
You'll have to use find() or first() or get() depending on your needs.
UPDATE
OK, after seeing your full code I have some ideas as to why it isn't working. First off you're sending res.send("Success"); before you're finished, I'm not positive but I think this causes it to stop running the rest of your code (haven't checked, could be wrong).
Also you're doing multiple async operations without chaining them so the contactQuery.first() will run before the twilio.sendSMS() is finished.
Inside twilio.sendSMS() you're calling response.success() / response.error(). These are for cloud methods, not web hooks, so I expect these would be throwing errors server-side (check the logs on the Dashboard).
Inside contactQuery.first() you are using alert() which isn't supported in cloud code.
I'm not sure if those mistakes will be caught early and throw errors or if they'll raise run-time exceptions, but they should be fixed, your code re-deployed and try again. Then report any errors in the server logs.
Yes, it's allowed, I'm using the same web hooks.
My guess is that you probably have defined security restriction on your Contact class that prevent the query to fetch anything. What's the security setting on this class ?
You can either try to relax the constrains, or login as a dummy user, and execute the query (approach that I chose).
cheers
-A

Categories

Resources