Edit: Got it working now. The trick is to move the HTTP.get to the server-side and use the simple:reactive-method package to get result from a method.
I could use some help figuring out how to display the result of Meteor.HTTP.Get. The docs are sketchy and there's no topics here that relates to my case.
I'm searching Foursquare to find local farmers & markets around you. then display the result in a map (no map yet). Here's the code:
The start page:
<template name="locator">
<a class="button" href="{{pathFor route='locatorMap' query='group=farmers'}}">Farmers</a>
<a class="button" href="{{pathFor route='locatorMap' query='group=markets'}}">Markets</a>
</template>
The soon-to-be map page. Edited: Mar 31, 2015
<template name="locatorMap">
<div class="list">
{{#each venues}}
<p>{{name}}. {{location.lat}}, {{location.lng}}</p>
{{/each}}
</div>
</template>
The routing (lib/router.js)
Router.route('/locator', {name: 'locator'});
Router.route('/locator/map', {name: 'locatorMap'});
The helper (client/locator/locator.js). Edited: Mar 31, 2015
// A static list of venue categories
Foursquare.categoryId = { ... };
Template.locatorMap.helpers({
venues: function() {
var search_group = Router.current().params.query.group;
var search_categories = Foursquare.categoryId[search_group].join(',');
var search_location = Geolocation.latLng();
if (search_location) {
// using simple:reactive-method
return ReactiveMethod.call('FoursquareSearch', search_categories, search_location);
} else {
throw new Meteor.Error("No Location", "Failed to get ...");
}
}
});
The method (server/methods/foursquare.js). Edited: Mar 31, 2015
Meteor.methods({
FoursquareSearch: function(categories, location) {
check(categories, String);
check(location, Object);
try {
var search_result = HTTP.call(
'GET', 'https://api.foursquare.com/v2/venues/search?',
{
timeout: 5000,
params: { ... }
}
);
return search_result.data.response.venues;
} catch (_error) {
throw new Meteor.Error("No Result", "Failed to fetch ...");
}
}
});
I can see data on the console. But i'm just not sure how how to pass it into a template helper. If you guys need more info, just let me know.
Any help is appreciated. Thx!
The question is really just: "How do I call a method from a helper?", which is answered here and here. However, in order for those solutions to work, you'll need your method to return a value rather than making an asynchronous HTTP call (which returns undefined). The path of least resistance is to define your FoursquareSearch method only on the server (put it under the /server directory) and to use a synchronous method invocation. For example:
Meteor.methods({
FoursquareSearch: function(cat) {
check(cat, String);
var search_location = Geolocation.latLng();
if (search_location) {
try {
// fill in the blanks here with params, timeout, etc.
var result = HTTP.get(...);
return result.data.response;
} catch (_error) {
throw new Meteor.Error("No Result", "Failed to fetch...");
}
}
}
});
Related
I have four checkbox and I want to check automatically checkbox with id = 2 if checkbox with id = 4 is checked.
I did the following but did not get the output. Could someone help me with this.
{#each category in checkboxList}}
{{input id = category.CHECKBOX_ID type="checkbox" checked=category.IS_CHECKED}}
{{#if category.CHECKBOX_ID == 4 && category.IS_CHECKED == true}}
{{action 'CheckSize'}}
{{/if}}
The checkboxList is
[
{"IS_CHECKED":false,"CHECKBOX_ID":1},
{"IS_CHECKED":false,"CHECKBOX_ID":2},
{"IS_CHECKED":true,"CHECKBOX_ID":3},
{"IS_CHECKED":false,"CHECKBOX_ID":4}
]
You'll want to manage the state of the checkboxes separately.
Here is an example I did for another SO question that had a similar problem to solve:
https://ember-twiddle.com/468a737efbbf447966dd83ac734f62ad
The gist of it is
we use a single action in response to a click of any checkbox:
#action
toggleChecked(id) {
const newTree = check(this.options, id);
this.set('options', newTree);
}
In this example (taken from the ember-twiddle), all of the logic is extracted to a pure-function named check.
Check itself is pretty involved, but because the application logic is different between that example and the problem you've run in to, I'll just show the entry point function:
export function check(tree, id, transform = toggle) {
if (tree === undefined) return undefined;
if (Array.isArray(tree)) {
return tree.map(t => check(t, id, transform));
}
if (tree.id === id || id === 'all') {
return checkNode(tree, id, transform);
}
if (tree.children) {
return checkChildren(tree, id, transform);
}
return tree;
}
This is just an example of how you can immutably modify the representation of all checkboxes by using a pure function. Your logic may vary.
Hope this helps :)
i am relatively new in django and angualarJs.The problem is that angularJs is not responding the get method properly.I have a webpage developed by django where i have a search field.For the execution of search i use a angularJs functionality that is ng-submit and write angularJs code to return value using get method.May be i made a mistake here.you can see my code... here is my template which containing the angularJs also...
<div class="navbar navbar-default " ng-controller="NavCtrl">
<form action="" class="navbar-form navbar-right" ng-submit="search()">
<input class="form-control col-lg-8" type="text" placeholder="Search" ng-model="term"></input>
</form>
</div>
<script>
app.controller("NavCtrl", ['$scope', '$http', '$location', '$q', '$timeout',
function NavCtrl($scope, $http, $location, $q, $timeout) {
$scope.results = ["Test"];
$scope.term = "";
$scope.reqs = "5";
$scope.pics = "45";
$scope.ddata = "asdasd";
$scope.ddata = $http.post("{% url 'get-nav-info' %}").success(
function (result) {
//$scope.reqs = result.data.data.num_request;
//$scope.pics = result.data.data.num_photo;
return result.data;
}
);
//$scope.reqs = $scope.ddata.num_request;
//$scope.pics = $scope.ddata.num_photo;
$scope.search = function () {
//alert("test");
//$location.absUrl("{% url 'search-term-show' %}").search({'term':$scope.term}).apply();
//$location.path("{% url 'search-term-show' %}").search({'term':$scope.term}).apply();
$http.get("{% url 'search-term-show' %}?term=" + $scope.term).success(function (result) {
return result.data;
});
//$scope.$apply();
}
}
]);
</script>
now the problem is that while i press enter ,there is no result,but if i manually write this URL which is http://www.kothay.com/searchphoto/?term=a in the address bar then the result is showing .In mention,this url is the that url which should be appear in the address bar when i press the enter to search my photos.But with the enter press its not appearing in the address bar and that's why the results are not showing.I hope you can understand what i am trying to say.May be there is a mistake in my code.Please help me to fix this problem.
You are doing thing wrong.
1st, the success is a defer of get, so return result.data and returns it to the get deferred and there it goes to the heaven. So if you would like to keep the current architecture it should look more like this
$scope.search = [];
getsearch = function () {
$http.get("{% url 'search-term-show' %}?term=" + $scope.term).success(function (result) {
$scope.search = result.data;
});
};
getsearch();
2nd that can still not update your UI cuz if the ctrl function is over and the digest is over before your response it wont update your UI cuz its in another scope (not $scope, but the programmatically term scope). The solution to this is to put your data in a service and in your ctr just do.
function ctrl($scope, myservice){
$scope.data = myservice;
}
ng-repeat="x in data.results"
Here is a full tutorial http://bresleveloper.blogspot.co.il/2013/08/breslevelopers-angularjs-tutorial.html
And last thing its just a good practice to always have .error(...)
The problem
I am trying to test some directives (code for both below). One of them is an "email" (called "epost" in the code(norwegian)) directive. The solution to this should work for all of them, so I am keeping it to this one for now.
Technologies: Angularjs, Jasmine, Requirejs, (grunt & karma running in Chrome)
The directive validates email addresses in two ways; on upshift and on blur. I can test the upshift without problems as you can see in the test below, but I can't figure out how to simulate a blur so the bind('blur') in the directive runs.
What I have done
I have tried to catch the compiled element like this:
elem = angular.element(html);
element = $compile(elem)($scope);
And then in the test i tried several permutations to trigger the blur with a console log just inside the bind function in the directive. None of the below works. It does not trigger.
elem.trigger('blur');
element.trigger('blur');
elem.triggerHandler('blur');
element.triggerHandler('blur');
element.blur();
elem.blur();
I based the injection and setup on this: To test a custom validation angularjs directive
The email directive in angularjs wrapped in requirejs
define(function() {
var Directive = function() {
return {
require: 'ngModel',
link: function(scope, elem, attrs, ctrl) {
var pattern = /^[A-Za-z0-9._%+-]+#[A-Za-z0-9.-]+\.[A-Za-z]{2,4}$/;
elem.bind('blur', function() {
scope.$apply(function () {
if (!elem.val() || pattern.test(elem.val())) {
ctrl.$setValidity('epost', true);
} else {
ctrl.$setValidity('epost', false);
}
});
});
ctrl.$parsers.unshift(function(viewValue) {
if (pattern.test(viewValue)) {
ctrl.$setValidity('epost', true);
return viewValue;
} else {
return undefined;
}
});
}
};
};
return Directive;
});
The test (using jasmine and requirejs)
define([
'Angular',
'AngularMocks',
], function () {
describe('Directives', function () {
var $scope;
var form;
beforeEach(module('common'));
beforeEach(function () {
var html = '<form name="form">';
html += '<input type="text" id="epost" name="epost" epost="" ng-model="model.epost"/>';
html += '</form>';
inject(function ($compile, $rootScope) {
$scope = $rootScope.$new();
$scope.model = {
epost: null
};
// Compile the element, run digest cycle
var elem = angular.element(html);
$compile(elem)($scope);
$scope.$digest();
form = $scope.form;
});
});
describe('(epost) Given an input field hooked up with the email directive', function () {
var validEmail = 'a#b.no';
var invalidEmail = 'asdf#asdf';
it('should bind data to model and be valid when email is valid on upshift', function () {
form.epost.$setViewValue(validEmail);
expect($scope.model.epost).toBe(validEmail);
expect(form.epost.$valid).toBe(true);
});
});
});
});
I have been able to figure out where I went wrong after some breakpoint debugging.
The "element" item I get out using the approach described in the top of the question is not actually the directive it self. It's an object which wraps the form and the directive.
Like this
{ 0: // The form
{ 0: // The directive (input element)
{
}
}
}
To actually simulate a blur on the directive it self, I did something like this
var directiveElement = $(element[0][0]);
directiveElement.blur();
After getting the element I wanted, and wrapping it in a jQuery object (may be optional), it worked like a charm. I then used the approach like in the test in the question with $setViewValue and checked the model value like this.
form.epost.$setViewValue('a#b.no');
directiveElement.blur();
expect($scope.model.epost).toBe('a#b.no');
expect($scope.form.epost.$valid).toBeTruthy();
Hope this could be of help to others trying to figure the directive testing out.
I too ran into a similar problem and it mystified me. My solution was to use JQuery to get the input and then use angular.element(input).triggerHandler('blur') to make it work. This is odd to me because I do not have to do this with the click event.
spyOn(controller, 'setRevenueIsInvalid');
var sugarRow = $(element).find('tr#ve_id_5')[0];
var amount = $(sugarRow).find('input.amount')[0];
angular.element(amount).triggerHandler('blur');
expect(controller.setRevenueIsInvalid).toHaveBeenCalled();
im working on a flash game with django backend using swfobject to embed the swf into the view,
however when i do externalinterface.call() from flash in InternetExplorer(Chrome and Firefox are fine), it returns null
the flash game itself works perfectly
Django view and embed code:
<div id="game_container">
<div id='flashContent'></div>
</div>
<script type="text/javascript" src="swfobject.js"></script>
<script type='text/javascript'>
var flashvars={{flashvars|safe}};
var params={wmode:"opaque", allowscriptaccess:"always" };
var attributes={id:"flashContent", name:"flashContent"};
swfobject.embedSWF("{{SWF_URL}}", "flashContent", "{{ appsettings.SWF_WIDTH }}", "{{ appsettings.SWF_HEIGHT }}", "10.0.0", false, flashvars, params, attributes);
</script>
function fqlearn_isEventInteresting(data) {
ln_log(['isEventInteresting',data]);
if (!BASE_URL) BASE_URL = data.baseURL;
ln_log(['got lesson?',fqlearn_findLearningModule(data) != null]);
return fqlearn_findLearningModule(data) != null;
//shuld return either true or false.
}
Flash AS3 code:
var isInteresting:Object = false;
try {
isInteresting = ExternalInterface.call('fqlearn_isEventInteresting', data);
} catch (e:Error) {
trace("error calling external interface");
// Container does not support outgoing calls :/
rpc.forceLogUncaughtError("ExternalInterface.call problem",
e.name, e.toString(), e.getStackTrace());
rest.apply(restThis);
return;
} catch (e:SecurityError) {
// Security sandbox nonsense :/
throw e;
}
if (isInteresting == null) {
// Something went wrong :/
rpc.forceLogUncaughtError("ExternalInterface.call problem", "JS_returned_null_error");
}
if (isInteresting) {
trace("showing learning blackout")
dispatch(CoordinationEvent.newLEARNING_ABOUT_TO_SHOW());
learningPendingData = {
rest: rest,
restThis: restThis
};
ExternalInterface.call() from Flash in InternetExplorer(Chrome and Firefox are fine), it returns null . how do i fix this?
Fixed it: console.debug was choking up Internet Explorer. I removed those and it worked.
Hey everyone,
i do the following query to get a user statuses:
FB.api(
{
method: 'fql.query',
query: 'SELECT message FROM statuses WHERE uid = ' + userId
},
function(data) {
// do something with the response
}
);
It works great when the number of result are more than 0.
but when there are no results, the callback function is not called at all.
i need to know if there are 0 rows returning from this query, is there any way to do it?
Thanks :)
First of all, the statuses table does not exists. You should be using status table.
The callback is always called but you should properly check against empty objects. Just paste this on the Javascript Test Console:
<fb:login-button scope="read_stream">
Grant access to statuses
</fb:login-button>
<button onclick="getStatuses()">Get Statuses</button>
<script>
window.getStatuses = function() {
FB.api(
{
method: 'fql.query',
query: 'SELECT message FROM status WHERE uid = me() AND time < 315532800'
},
function(data) {
if(!isEmpty(data)) {
for(var key in data) {
var obj = data[key];
console.log(obj['message'])
}
} else {
console.log("data is empty")
}
});
};
function isEmpty(obj) {
for(var prop in obj) {
if(obj.hasOwnProperty(prop))
return false;
}
return true;
}
</script>
Here I am checking for statuses before 1/1/1980 to insure that an empty result is returned. In your console you should note the data is empty response.
When there are no results from a query, you should be getting an empty array.
Also, there isn't a FQL table named "statuses", it's "status".