UPDATED CODE: i, I'm new to Javascript programming and getting an undefined variable when trying to assign a new variable from a method.

I'm using node.js and creating a redis server using the redis-client in the "client variable".

var redis = require("redis");
var client = redis.createClient();

client.on("error", function (err) {
console.log("Error " + err); });

var numberPosts;

client.get("global:nextPostId", function(err, replies) {
  numberPosts = replies;
  console.log(numberPosts);
});

console.log(numberPosts);

When I call console.log inside the call back function it returns the proper value, however when I call the console.log outside of the callback function it returns "undefined". I'm trying to assign the value that is inside the callback function to the global variable numberPosts.

Any help is much appreciated, thanks.

Matt

share|improve this question
    
When var numberPosts = client.get("global:nextPostId", redis.print); is executed it results in undefined. – Matikus1trillion Feb 15 '11 at 13:49
    
You simply can't do that like this. See my answer for more details. – Shadow Wizard Feb 15 '11 at 14:26
up vote 4 down vote accepted

I believe this will work:

client.get("global:nextPostId", function (err, reply) {
    console.log("Number of posts: " + reply.toString());
})

The AJAX call is asynchronous so it doesn't have return value.. instead you have to use callback function and only there you have the value returned by the server method.

Edit: to assign the return value to global variable, first declare global variable:

var _numOfPosts = "";

Then:

client.get("global:nextPostId", function (err, reply) {
     _numOfPosts = reply.toString());
})

However, the value won't be available until the AJAX call is finished so your original code can't work. There is not direct return value to store.

You can set timer to some reasonable response time, then have the code using the global variable in there.

Edit II: in order to call the method again once it's finished, have such code:

var _nextPostCallCount = 0;
function GetNextPost() {
   //debug
   console.log("GetNextPost called already " + _nextPostCallCount  + " times");

   //sanity check:
   if (_nextPostCallCount  > 1000) {
      console.log("too many times, aborting");
      return;
   }

   //invoke method:
   client.get("global:nextPostId", function(err, replies) {
      numberPosts = parseInt(replies.toString(), 10);
      console.log("num of replies #" + (_nextPostCallCount + 1) + ": " + numberPosts);

      //stop condition here.... for example if replies are 0
      if (!isNaN(numberPosts) && numberPosts > 0)
         GetNextPost();
   });

   //add to counter:
   _nextPostCallCount++;
}
GetNextPost();

This will call the method over and over until the result is 0 or you pass some hard coded limit to prevent endless loop.

share|improve this answer
    
That works and we've been able to get that to work. But the problem we have is when we try to assign the value "reply" into a global variable. – Matikus1trillion Feb 15 '11 at 13:52
    
@Mat see my edit.. – Shadow Wizard Feb 15 '11 at 14:20
    
Show wizard: Thanks for your help on this one. Unfortunately it is still returning undefined when I try to access _numOfPosts outside of the callback function. – Matikus1trillion Feb 15 '11 at 14:42
    
@Mat try window.setTimeout(function() { alert("num: " + _numOfPosts); }, 3000); this will show the alert after 3 seconds when the global variable should have value. – Shadow Wizard Feb 15 '11 at 14:44
    
As I'm rereading this it looks like you are staying this may not be possible. Let me tell you what we've trying to achieve. We essentially just want to return the value of global:nextPostId into a variable, and then loop through each post id and spit out each post body into a websocket. – Matikus1trillion Feb 15 '11 at 14:45

Try this instead to see errors:

var redis = require("redis"); 

client = redis.createClient(); 

client.on("error", function (err) {
console.log("Error " + err); });

//note the error logging
var numberPosts = client.get("global:nextPostId", function (error, response) {
  if (error) {
    console.log("async: " + error);
  } else {
    console.log("programming: " + response);
  }
});

console.log("is lotsa fun: " + numberPosts);

As Shadow Wizard has pointed out you are trying to use numberPosts before there is something in it, as client.get() hasn't returned anything.

Read this to get a handle on node.js flow:

http://www.scribd.com/doc/40366684/Nodejs-Controlling-Flow

share|improve this answer
1  
This is exactly the same as what was originally posted, except that you've introduced a global variable ("client"), right? Why would this make any difference? – Pointy Feb 15 '11 at 13:45
    
That's not where were having the problem. Note the "," in the orignal code after require("redis"). We're specifically having the problem with the var numberPosts = client.get("global:nextPostId", redis.print); That is resulting in undefined. – Matikus1trillion Feb 15 '11 at 13:48
    
I updated my code with some error logging – jpstrikesback Feb 15 '11 at 14:15
1  
There is no error, he's trying to use the response before it arrive. – Shadow Wizard Feb 15 '11 at 14:20
    
indeed, updated...:) – jpstrikesback Feb 15 '11 at 14:32

I was facing the the same issue when I applied the MVC framework. To solve the problem, I employed the render function.

In the posts Model

exports.get = function(id,render) {
    client.incr('post:id:'+id, function(err, reply) {
    render(reply);
    });
};

In the posts Controller

exports.get = function(req, res) {
    posts.get('001', function (data){res.render('index',{post:data});});

};
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.