for some reason when I run npm start and I hit the browser, I am getting this stack trace with this error.
TypeError: $.ajax is not a function
at getLocationFromIp (G:\Github\Expressjs\nodetest1\routes\index.js:13:7)
at G:\Github\Expressjs\nodetest1\routes\index.js:24:14
Would someone be able to tell me why? Here is my code. Thanks!
var express = require('express');
var router = express.Router();
var externalip = require('external-ip');
var $ = require('jquery');
getLocationFromIp = function() {
$.ajax({
url:"freegeoip/json/",
type: "GET",
data: null,
dataType: "json",
success: function(){console.log("success!")}
});
}
router.get('/', function(req, res) {
var ip = getLocationFromIp();
res.render('index', { 'ip' : "hi"});
});
for some reason when I run npm start and I hit the browser, I am getting this stack trace with this error.
TypeError: $.ajax is not a function
at getLocationFromIp (G:\Github\Expressjs\nodetest1\routes\index.js:13:7)
at G:\Github\Expressjs\nodetest1\routes\index.js:24:14
Would someone be able to tell me why? Here is my code. Thanks!
var express = require('express');
var router = express.Router();
var externalip = require('external-ip');
var $ = require('jquery');
getLocationFromIp = function() {
$.ajax({
url:"freegeoip/json/",
type: "GET",
data: null,
dataType: "json",
success: function(){console.log("success!")}
});
}
router.get('/', function(req, res) {
var ip = getLocationFromIp();
res.render('index', { 'ip' : "hi"});
});
Share
Improve this question
asked Mar 26, 2016 at 17:03
Patrick GuanPatrick Guan
371 silver badge3 bronze badges
7
- Try adding the code inside of $(document).ready(function(){}) function – Dale Commented Mar 26, 2016 at 17:04
-
@Dale — What
document
? – Quentin Commented Mar 26, 2016 at 17:07 - The problem probably lies with a-sync loading of Jquery via the require function. Is there a way to fire getLocationFromIp function AFTER Jquery script loads? That it likelly to solve your problem. – Elvanos Commented Mar 26, 2016 at 17:07
-
@Elvanos — Since when was
require
async? – Quentin Commented Mar 26, 2016 at 17:08 - Hmm... is there a way to make jquery fire after the require loads? if that is the issue – Patrick Guan Commented Mar 26, 2016 at 17:14
2 Answers
Reset to default 6See the documentation:
For jQuery to work in Node, a window with a document is required. Since no such window exists natively in Node, one can be mocked by tools such as jsdom. This can be useful for testing purposes.
var externalip = require('external-ip');
require("jsdom").env("", function(err, window) {
if (err) {
console.error(err);
return;
}
var $ = require("jquery")(window);
function getLocationFromIp() {
$.ajax({
url: "freegeoip/json/",
type: "GET",
data: null,
dataType: "json",
success: function() {
console.log("success!")
},
error: function() {
console.log("error", arguments[2])
}
});
}
var ip = getLocationFromIp();
console.log(ip);
});
You'd probably be better off using an HTTP library designed to work with Node from the outset, such such as request.
If you are using jquery to just make a http request, you can probably use the http or request node module to do that instead.
var express = require('express');
var router = express.Router();
var externalip = require('external-ip');
var http = require('http');
getLocationFromIp = function(done) {
var options = {
host: "freegeoip",
port: 80,
path: "/json"
};
var request = http.get(options, function(response) {
var result = "";
var responseCode = response.statusCode;
response.on('data', function(data) {
result += data;
});
response.on('end', function() {
if(responseCode >= 400)
return done(result, null);
else
return done(false, JSON.parse(result));
});
});
request.on("error", function(error){
return done("Error handling error", null);
});
request.end();
}
router.get('/', function(req, res) {
var ip = getLocationFromIp(function(error, ip){
res.render('index', { 'ip' : "hi"});
});
});