This is my piece of code, which works correctly (adds records), but throws an error after addition:
Uncaught Error: Invariant Violation: enqueueCallback(...): You called
setProps, replaceProps, setState, replaceState, or
forceUpdate with a callback that isn't callable.
handleSubmit: function(e) {
e.preventDefault();
return $.post('', {page: this.state},
function(data) {
this.props.handleNewPage(data);
return this.setState(this.getInitialState(), 'JSON');
}.bind(this)
);
}
There are no routes for now. Can someone help me to solve this?
The second (optional) parameter to setState is a callback function, not a string. You can pass a function that will be executed once the operation is completed.
You actually invoke getInitialState instead of providing a reference to the function itself on the line return this.setState(this.getInitialState(), 'JSON'); and the second argument should never be anything but a callback function.
this.setState expects either a function that should return a state object as a single argument, or an object to merge the current state with (plus optionally a callback as a second argument to run after state has been set). So either you provide just a function that returns the new state, or you provide an object that the current state should be merged with as a first argument and a callback that will be executed after the state has been set as second argument.
Either this.setState(this.getInitialState) or this.setState(this.getInitialState()) or this.setState(newState, callback).
Check out the signature in the API here.
Related
I have a block of code like that
function doA (callback) {
//do something...
callback();
}
function doB (callback) {
//do something...
callback();
}
function doC () {
//do something...
}
i know it's a bad practice and have to avoid it, but i am trying to understand why when i called the functions as
doA(doB(doC)));
it throwed an error that "callback is not a function" ?
But when i tried:
doA(doC);
everything was ok.
edited: i have tried to use chrome dev tool to figure out how javascript callstack works here, and i found out that the call stack be like:
doC
doB
there isn't doA function, so why js avoids adding doA() to the callstack?
it throwed an error that "callback is not a function" ?
You call doA and pass the return value of doB(doC) as the first argument.
doB has no return statement, so it returns undefined.
doA tries to call the first argument (which has the value undefined) as a function, which it isn't, so it fails.
It isn't entirely clear what you are trying to achieve (since your example code has been abstracted so much), but you should probably investigate the Promises API which would let you do something like:
doA().then(doB).then(doC);
You are passing result of doB(doC) as the argument of doA but it is not a function:
doB(doC); // undefined
doA(undefined); // throws: callback is not a function
For callback you need to pass function and doB(doC) will execute it and will return undefined. And that undefined value will get passed to doA(undefined) and thats why you are getting -
callback is not a function
because doB it's not returning a function.
that expression means that the output of doB is passed as argument to doA, but since doB is not returning a function you get the error.
Zookeeper provides a getChildren method that takes in the path of the node and returns the children of that node in a callback. It also sets a watch during the process and calls the watcher callback when a watch is triggered
getChildren(path, function(err,event){
//this is the watcher callback
},
function(err,children,stats){
//children callback
}
)
So if I use the bluebird's Promise.promisify to promisify this function. How do I know that the promise this function is returning is the watcher or the children ??
If I understand the getChildren() interface correctly, the last callback is designed to be called once with the list of child objects. The first callback is a watcher callback that may be called an indefinite number of times to notify you of various changes occurring.
Given that, the last callback could fit with a promise. The first callback cannot and must remain a callback. In addition, the second callback is returning multiple results (which does not fit perfectly with promises) so you have to make allowances for that too using multiArgs and .spread.
So, you could do something like this:
let getChildrenP = Promise.promisify(getChildren, {multiArgs: true});
getChildrenP(path, function(err, event) {
// watcher event occurred here
// this may get called multiple times
}).spread(function(children, stats) {
// children are available now
}).catch(function(err) {
// error here
});
downloadPhoto('http://coolcats.com/cat.gif', handlePhoto)
function handlePhoto (error, photo) {
if (error) console.error('Download error!', error)
else console.log('Download finished', photo)
}
console.log('Download started')
I know handlePhoto as a callback passed into downloadPhoto, but I'm confused with handlePhoto function itself, the first parameter is error, is that means js recognize it as an error? can I use "err" replace or other parameter name.And what is the second parameter in console.log means, I can't find exactly answer for it yet.
When downloadPhoto function invocation is completed, it calls handlePhoto with some parameters.
According to convention ( rule generally followed ), first parameter should always be error & rest can be result values.
function downloadPhoto(url , callback ){
if(gotImageFromRemoteSuccessfully){
callback(null,successResponse)
} else{
callback(whatWentWrong , null );
}
}
the first parameter is error, is that means js recognize it as an error?
No, it means that when that function is called, the first argument passed to it will be placed in a variable named error.
can I use "err" replace or other parameter name
Yes. You can call the arguments whatever you want according to the normal rules of argument naming.
And what is the second parameter in console.log
That is the second thing that you want to be logged. console.log takes any number of arguments and logs them all.
Thanks everyone, I think if I add callback && callback(error ,result) in side downloadPhoto function, it would be more clear for me. But there is a follow up question here I saw many functions which don't have callback && callback(), how could these function pass parameter to its callback function?
I am fairly used to RX having used it in .NET and Java, I am expecting to be able to do the following:
Rx.Observable.fromCallback(websocket.onmessage)
.map(...)
.subscribe(...);
however, the console has the following:
Uncaught TypeError: Rx.Observable.fromCallback(websocket.onmessage).map is not a function
which would appear to indicate that the fromCallback is not returning an Observable.
What am I doing wrong here? Have I misunderstood what fromCallback is doing and I need to use a Subject? Can I not wrap some arbitrary handler in an observable?
You are actually looking for fromEvent or fromEventPattern:
Rx.Observable.fromEvent(websocket, 'message').map(/*...*/).subscribe();
Rx.Observable.fromEventPattern(
function add(h) { websocket.addEventListener(h); },
function remove(h) { websocket.removeEventListener(h); })
.map(/*...*/)
.subscribe();
The first one will attempt to use some of the standard ways of subscribing to an event emitter, which WebSocket is. However, if that fails you can use fromEventPattern instead to specify how handlers are added or removed from your object.
One additional note, JavaScript does not pass along an implicit reference to the instance of the object you are using as C# and Java do, so your code fromCallback(websocket.onmessage) is not passing along websocket, it is passing along the reference to the method from the function prototype. this will be determined at execution time.
Rx.Observable.fromCallback is for functions whose last argument is a callback function which is a standard pattern for asynchronous JavaScript code. Further, the fromCallback method does not return an Observable it returns a function that when called returns an Observable i.e.
function methodWithCallback(arg0, arg1, cb) {
setTimeout(function() {
cb(arg0 + arg1);
}, 2000);
}
var newMethod = Rx.Observable.fromCallback(methodWithCallback);
//[After 2 seconds] 3
newMethod(1, 2).subscribe(console.log.bind(console));
I am trying to pass a callback to a function, but keep getting the error,
Uncaught TypeError: callback is not a function.
loadContacts: function () {
var pageNumber = this.state.pageNumber,
pageSize = this.state.pageSize;
BasketService.getContacts(pageNumber, pageSize, function(contacts){
contacts = this.convertPropertyNames(contacts);
this.setState({
contacts: contacts
});
}.bind(this));
},
// trying to pass function callback here
listenerForRemoveContact: function(data){
BasketService.removePerson(data.id, this.loadContacts());
},
this.loadContacts() calls loadContacts and passes its return value to removePerson.
loadContacts doesn't have a return statement, so that value is undefined.
You are trying to use undefined as if it were a function.
If you want to pass loadContacts as the callback function, then don't call it: Remove the ().
Note that this will change the value of this inside the function, so you should also use bind() to maintain the context.
BasketService.removePerson(data.id, this.loadContacts);
^ you probably want to pass in the function object, not the result of calling the function
passing in
this.loadContacts()
will pass in the value which loadContacts returns (in this case it isn't returning anything)
Your code this.loadContacts() calls the function loadContacts and passes its return value to removePerson as argument.
loadContacts doesn't return anything, so the return value of that function is undefined.
If you want to pass loadContacts as the callback function, then don't invoke it just remove the invoking () from it.
Just pass like this
removePerson(data.id, this.loadContacts);
That's it.