Method Callback Returning Undefined [CoffeeScript] - coffeescript

I am calling a simple google api using an HTTP method on the server. It appears I am getting a json object back, yet the callback on the client seems to return an undefined object.
My guess is somehow the result isn't making it to the callback in time. A bit confused.
Full code here:
if Meteor.isClient
Meteor.startup () ->
console.log "Client Started."
Meteor.call("getGeocode", 94582, (error, result) ->
console.log "GeoCode returned to client, #{result}."
Session.set("latitude", result))
Template.results.latitude = () ->
Session.get("latitude")
Template.results.longitude = () ->
"longitude"
if Meteor.isServer
Meteor.startup () ->
console.log "Server Started"
Meteor.methods
"getGeocode": (zipCode) ->
result = HTTP.call("GET", "http://maps.googleapis.com/maps/api/geocode/json?address=#{zipCode}&sensor=false")
console.log "Geocode called, returning #{result}."

Your getGeocode method is returning undefined because CoffeeScript will automatically return the result last statement in the function, which in this case is a console.log.
I don't think result is really want you want though. I recommend including util at the start of your isServer section like so:
if Meteor.isServer
util = Npm.require 'util'
Now you can call console.log util.inspect result, {depth: null} to see what it's made of. I think what you may actually want to return is result.data.results[0]. Your code could look something like:
if Meteor.isClient
Meteor.startup () ->
console.log "Client Started."
Meteor.call("getGeocode", 94582, (error, result) ->
Session.set("latitude", result.geometry.location.lat))
Template.results.latitude = () ->
Session.get("latitude")
Template.results.longitude = () ->
"longitude"
if Meteor.isServer
util = Npm.require 'util'
Meteor.startup () ->
console.log "Server Started"
Meteor.methods
"getGeocode": (zipCode) ->
result = HTTP.call("GET", "http://maps.googleapis.com/maps/api/geocode/json?address=#{zipCode}&sensor=false")
geoData = result.data.results[0]
console.log util.inspect geoData, {depth: null}
geoData

Related

Coffeescript error "undefined is not a function" in hubot

I'm making call to my django app that returns a JSON object and I'm using the following code to do so:
robot.hear /lunch for today/i, (res) ->
robot.http("http://my_ip_address/show")
.header('Accept', 'application/json')
.get() (err, res, body) ->
data = JSON.parse body
res.send data.food
but it returns ERROR TypeError: undefined is not a function in the console. What's wrong with this?
is should look like this:
module.exports= (robot) ->
robot.hear /lunch for today/i, (msg) ->
robot.http("http://my_ip_address/show")
.header('Accept', 'application/json')
.get() (err, res, body) ->
console.log res.statusCode
data = JSON.parse body
msg.send data.food
I believe the reason it is failing is because you are using res in the place of msg and then res again in the context of the function .get()
I'm guessing the error is on this line:
.get() (err, res, body) ->
Instead of passing the callback as an argument to get, you're calling get with no arguments and then trying to call the result (which is undefined) as though it were a function. My CoffeeScript is rusty, but I think you want this instead:
.get (err, res, body) ->
It might be incompatible version of installed hubot and documentation but I found out the res from an http method has no send, but the one from the /hear command does.
robot.hear /lunch for today/i, (res) ->
robot.http("http://my_ip_address/show")
.header('Accept', 'application/json')
.get() (err, msg, body) ->
data = JSON.parse body
res.send data.food
This should work, but either the official documentation is wrong, either the default installation of hubot is outdated.

Understanding coffescript functions scope and return object kind - while trying to get JSON

I would like to have some function getTagsDict() visible to broder scope, which will be responsible for some GET request to the server and returning dictionary, which can be then easily accesed in loop like:
for k,v of getTagsDict()
For now below code returns some js crap (or at least for js-newbie): http://i.imgur.com/A3YtobD.png
getTagsDict = () ->
$.get '/notifications/ajax_avalaible_search_tags/', (data) ->
data
$ ->
$('#ajax_search_input').on 'keyup', (e) ->
for k,v of getTagsDict()
console.log "#{k} and #{v}"
But when doing GET just inside the calling method everything works well:
$ ->
$('#ajax_search_input').on 'keyup', (e) ->
$.get '/notifications/ajax_avalaible_search_tags/', (data) ->
for k,v of data
console.log "#{k} and #{v}"
QUESTION: How should I use coffee's functions to be globaly and to be utilized as described?
The clue was to build getTagsDict as function with asynchronus ajax call. It can look for example like this:
getTagsDict = ->
strReturn = ""
jQuery.ajax
async: false
url: "/notifications/ajax_avalaible_search_tags/"
success: (data) ->
strReturn = data
strReturn

Parse.history.start doesn't seem to work

When using the code below and entering the address index.html#players I am not taken to the players route, in fact nothing happens at all. However, if I open up the dev tools and run Parse.history.checkUrl() it works as expected. When I remove Parse.history.start() and do it manually I get TypeError: undefined is not a function.
$(() ->
$wrapper = $('#wrapper')
Router = Parse.Router.extend({
routes: {
'selected': 'selected'
'players': 'players'
'': 'teams'
}
selected: () ->
console.log('selected')
$wrapper.removeClass()
$wrapper.addClass('selected')
players: () ->
console.log('players')
$wrapper.removeClass()
$wrapper.addClass('players')
teams: () ->
console.log('teams')
$wrapper.removeClass()
$wrapper.addClass('teams')
})
window.router = new Router()
Parse.history.start()
)
If anyone else is having this problem and urgently needs a work-around I have found that the code below works.
window.router = new Router()
try
Parse.history.start({})
catch err
console.log(err)
Parse.history.checkUrl()
window.onhashchange = Parse.history.checkUrl

return value from a jquery get callback function

It would be very useful to me if you could help me fix this function:
textParseQuery = (txtSnippet) ->
queryUrl = "http://localhost:8083/txtParse/#{txtSnippet}"
console.log queryUrl
callback = (response) =>
parsed = $.parseJSON response
companies = parsed.map (obj) -> new Company(obj.name, obj.addr)
companies
res = $.get queryUrl, {}, callback
console.log res
I would like to fetch the results from the callback so that the textParseQuery function could return a value.
The point of a callback is it's asynchronous, your response comes in the callback, so you need to handle the rest of the execution from the callback (e.g., the console.log res is going to execute before your callback is called, since it's part of the same synchronous execution of your ajax call).
textParseQuery = (txtSnippet) ->
queryUrl = "http://localhost:8083/txtParse/#{txtSnippet}"
callback = (response) ->
parsed = $.parseJSON response
companies = parsed.map (obj) -> new Company(obj.name, obj.addr)
# proceed from here
console.log companies
$.get queryUrl, {}, callback
Additional note: the fat arrow is unnecessary here, it's used to rebind what this refers to, but you aren't referencing this at all in your callback. If you're learning coffee, most editors will have plugin/modules to quickly compile coffee to JS, so use that to see what a given coffee syntax compiles to in JS (e.g., take a look at the diff between using -> and => when you compile your coffee)
I have discovered IcedCoffeeScript helps streamline the asynchronous control flow with await and defer. This is what I have tried to achieve. The code structure is how I pictured it
# Search for 'keyword' on twitter, then callback 'cb'
# with the results found.
search = (keyword, cb) ->
host = "http://search.twitter.com/"
url = "#{host}/search.json?q=#{keyword}&callback=?"
await $.getJSON url, defer json
cb json.results

Classes in CoffeeScript

I have some code on CoffeeScript (run under PhantomJS):
class Loadtime
constructor: ->
#page = require('webpage').create()
check: (uri) ->
time = Date.now()
#page.open uri, (status) ->
console.log 'foo'
if 'success' is status
time = Date.now() - time
return time
else
return "FAIL to load #{uri}"
loadtime = new Loadtime()
console.log loadtime.check('http://example.com') # undefined
phantom.exit()
Class have constructor and one public method.
Line #page.open uri, (status) -> ... must call callback function, but it does not call it (line console.log 'foo' does not execute).
Why?
You're calling phantom.exit immediately, so it has no time to load the web page. Add a callback to your check function that you call at the end of the open callback, and call phantom.exit inside the callback passed to check:
class Loadtime
constructor: ->
#page = require('webpage').create()
check: (uri, cb) ->
# ...
#page.open uri, (status) ->
# ...
cb()
loadtime = new Loadtime
loadtime.check 'http://www.example.com/', (time) ->
console.log time
process.exit()