Leaflet Search Control - Cannot read property 'call' of undefined - php

I am having an issue with Leaflet Control Search, I am testing on C9.io, using Laravel 5.2, I am trying to search a L.geojson layer but all it comes up with is "Location not Found"
and the console gives error:
"Cannot read property 'call' of undefined"
I have a global variables that holds the map, L.geojson layers, and tiles.
var map, allcalls, mapquest;
mapquest = new L.TileLayer("http://{s}.mqcdn.com/tiles/1.0.0/osm/{z}/{x}/{y}.png", {
maxZoom: 18,
subdomains: ["otile1", "otile2", "otile3", "otile4"],
});
map = new L.Map('map', {
center: new L.LatLng(39.90973623453719, -93.69140625),
zoom: 3,
layers: [mapquest]
});
var promise = $.getJSON("leaflet_php/get_users.php");
promise.then(function(data) {
allcalls = L.geoJson(data, {
onEachFeature: function (feature, layer) {
layer.bindPopup(feature.properties.fn + '<br>' +feature.properties.gender + '<br>' + feature.properties.addr + '<br>'+ feature.properties.city );
}
});
map.fitBounds(allcalls.getBounds(), {
padding: [20, 20]
});
allcalls.addTo(map);
});
Then I start the L.control.search, and it shows on the map but when I search I get no results the loader gif never stops and I get console error "Cannot read property 'call' of undefined"
var controlSearch = new L.Control.Search({
layer: allcalls,
position:'topleft',
propertyName: 'city',
});
map.addControl( controlSearch );
I am generating the json using https://github.com/bmcbride/PHP-Database-GeoJSON. My Json has at least 1000 features, each feature has 30 properties. So this is an abbreviated version. This is a sample of the json I get:
{"type":"FeatureCollection","features":[{"type":"Feature","geometry": {"type":"Point","coordinates":[-80.191626,26.339826]},"properties":{"id":1,"fn":"SAMUEL","mi":null,"ln":"STANTON","name_pre":"MR","addr":"9 HONEYSUCKLE DR","apt":null,"city":"AMELIA","st":"OH","zip":45102,"z4":9722,"dpc":99,"fips_cty":25,"latitude":26.339826,"longitude":-80.191626,}},
Any help is greatly appreciated. Thanks in advance.

You should instantiate L.Control.Search within your Promise callback, or at least use the setLayer() method within that callback.
It looks like you have a classic asynchronous issue: you initiate an AJAX request (through jQuery's getJSON), which will assign the value of your allcalls variable once resolved.
In parallel, you instantiate your L.Control.Search and specify allcalls as the Layer Group to be searched in. However, at that time, the AJAX is still processing (i.e. not resolved), so allcalls is still unassigned (i.e. undefined).
Therefore your Search Control knows nothing about the L.geoJson layer group that is built later on in the AJAX resolution.

Related

how to pass param object to d3.json?

My existing extJS code passes readData.php a param object
params: {
start: 0,
limit: 1000,
proc_nm: 'sel_bkng_srch',
srchStrng: '',
parms: [[dnStrng,1],[mtStrng,1],[dtFromStrng,1],[dtToStrng,1]],
connId: 'AW'
}
so it can call a stored procedure which I want to share with d3. After lots of attempts, latest is:
d3.json("php/readData.php")
.header("params", "params: {start: 0,limit: 1000,proc_nm: 'sel_bkng_srch',srchStrng: '',parms: [1,1],[2,1],[3,1],[4,1]],connId: 'AW'}")
.get(function(error, data) {
console.log('readData: ', error) ;
});
I do not have the syntax correct to pass the object with d3.json. Everything else is functional I think - php gets called, returns an empty success object (php code needs looking at here) which is picked up back in d3. tia.

how to send object array in ext js 4 to server side?

i am working in extjs4 MVC where I have been working on task to create question answer page functionality.There are 4 questions to be displayed with there options.I have getting all the selected questions and answers in controller.But I didnot know how to send to srver side using models method.I am getting stuck at this point.
Here is my some controller code
1)
check:function()
{
console.log("Inside check function.");
//creating objects in javascript
var obj=new Object();
for(var i=0;i<=5;i++)
{
var inputs = document.getElementsByName(i);
var radio = "";
for (var j = 0; j < inputs.length; j++) {
if (inputs[j].checked) {
name = inputs[j].name;
value = inputs[j].value;
//obj[i].name1=name;
obj[i]={'questionId':name,'option':value};
console.log("questionId="+name +" value="+ value);
console.log("object name="+ obj[i].questionId+" Object value="+obj[i].option);
}// End of if statment
}// End of inner for loop
}//End of outer for loop
}// End of check function
2)here is I have getting some output in firebug
questionId=1 value=Aus QbqnsController.js:39
questionId=2 value=india QbqnsController.js:39
questionId=3 value=England QbqnsController.js:39
questionId=4 value=Srilanka
Actually i want to use model class methods save() . but how can I use it.
please give me some suggestions.
3)here is my model classs
Ext.define('Balaee.model.qb.QbqnsModel',{
extend: 'Ext.data.Model',
idproperty:'questionId',//fields property first position pk.
fields: ['questionId','question','languageId','userId','creationTime','questionStatusId','keyword'],
hasMany:{
model:'Balaee.model.qb.QbqnsoptionModel',
foreignKey:'questionId',
name:'options',
},
proxy:
{
type:'ajax',
api:
{
read:'http://localhost/balaee/balaee/index.php?r=QuestionBank/qbpaper/setuseranswer',
create:'http://localhost/balaee/balaee/index.php?r=QuestionBank/qbpaper/setuseranswer',
},//end of api
reader:
{
type:'json',
},//end of reader
writer:
{
type:'json',
root:'records',
},//End of writer
}
});
If you're using Ext MVC and you're questions are model instances stored inside a store, you can use store.sync() which will batch the data in different states (add, edit, deletes etc) and sync them with the relevant store or model proxy url, or the api urls specified.
This has the benefit of sending arrays of objects back in a single request, but then of course you need to separate them on the server side before processing.
Inside your function you can send them using Ext.Ajax.request
Ext.Ajax.request({
url: 'your_server_page.php ',
params: {
Your_Object_Name : JSON.stringify(Your_Object_Array)
}
});

Understanding geolocation on tweets

I'm trying to get geolocation from tweets.
For my tests, I posted new tweets geo-referenced but when I got the json of them, the element 'geo' is null. Why? What's wrong with them?
I don't want to search by range and geolocation: I want to search some tweets indexed by a particular hashtag and then retrieve 'geo' json element.
I tried to search other tweets (not mine) and sometimes I got 'geo' element as a full object, with coordinates array.
So, what can I do to have 'geo' element not null?
I did 4 posts geo-referenced: my tweets
The location is: 44.694704,10.528611
Edit: Added geocode param
This is what I've done server-side (pure php):
$conn = new OAuth (CONSUMER_KEY, CONSUMER_SECRET);
$conn->setToken (ACCESS_TOKEN, ACCESS_TOKEN_SECRET);
$conn->fetch (API_URL, array ('q' => '#testhashtagandgeo', 'geocode' => '44.694704,10.528611,4km'));
echo $conn->getLastResponse ();
I used PHP OAuth base and each constant is defined correctly, so it works good.
Client-side (ExtJS):
Ext.onReady (function () {
Ext.Ajax.request ({
url: 'proxy.php' ,
disableCaching: false ,
success: function (xhr) {
var js = Ext.JSON.decode (xhr.responseText);
Ext.each (js.results, function (tweet) {
if (tweet.geo !== null) {
console.log ('lat = ' + tweet.geo.coordinates[0] + ' - lng = ' + tweet.geo.coordinates[1]);
}
});
console.log (js);
} ,
failure: function (xhr) {
console.log ('something\'s wrong!');
}
});
});
Thanks in advance.
Wilk
You need to read the documentation
Location data is only included if the query includes the geocode parameter, and the user Tweeted with Geo information.
So, you need to add something like this to your query
&geocode=37.781157,-122.398720,25mi
Or whichever location you want.

Why a layer was incorrectly reloaded?

I've got a problem that was discribed over there:
how to correctly reload fusion tables layer?
Briefly:
i have a fusion table that changes very often.
And i have a javascript code that allows to visualize location information from database:
Thanks everyone, i've managed to solve this thing. This is the code that works as it should:
var map;
var layer;
function initialize() {
map = new google.maps.Map(document.getElementById('map_canvas'), {
center: new google.maps.LatLng(60,30),
zoom: 9,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
layer = new google.maps.FusionTablesLayer({
query: {
select: 'location',
from: '3415835'
}
});
layer.setMap(map);
refreshMap();
}
function refreshMap(){
layer.setOptions({
query: {
select: 'location',
from: '3415835',
where: "location not equal to" + (-1 * Math.floor(Math.random() * 10000000)).toString()
}
});
setTimeout('refreshMap()',5000);
}
At first t thought that my code is wrong. But after testing i discovered that layer is
being reloaded incorrectly: when new point is added i can see it on one zoom level but on
another level it dissapears. i dnon't know what's causing this: browser is cashing map or
script is wrong or smth else. Can someone help me?

JavaScript: Backbone.js populate collection of models

Here is what I have so far:
var Item = Backbone.Model.extend({
defaults: {
id: 0,
pid: 0,
t: null,
c: null
},
idAttribute: 'RootNode_', // what should this be ???
url: 'page.php'
});
var ItemList = Backbone.Collection.extend({
model: Item,
url: 'page.php',
parse: function(data) {
alert(JSON.stringify(data)); // returns a list of json objects, but does nothing with them ???
}
});
var ItemView = Backbone.View.extend({
initialize: function() {
this.list = new ItemList();
this.list.bind('all', this.render, this);
this.list.fetch();
},
render: function() {
// access this.list ???
}
});
var view = new ItemView();
Current (expected) json response:
{
"RootElem_0":{"Id":1,"Pid":1,"T":"Test","C":"Blue"},
"RootElem_1":{"Id":2,"Pid":1,"T":"Test","C":"Red"},
"RootElem_2":{"Id":3,"Pid":1,"T":"Test2","C":"Money"}
}
This successfully polls page.php and the backend acts on $_SERVER['REQUEST_METHOD'] and returns the required information, however I don't know why the collection is not filled.
In the parse function of ItemList it properly shows me all the output, but it does nothing with it.
I left some comments in the code for some more precise questions, but the main question is why doesn't the collection populate with the obviously received data?
Modify your parse method to:
parse: function(response){
var parsed = [];
for(var key in response){
parsed.push(response[key]);
}
return parsed;
}
To follow conventions, change list inside ItemView to model. Also in render():
render: function() {
var template = _.template("<div>some template</div>");
this.model.each(function(item){
this.$el.append(template(item.toJSON()));
}, this);
return this;
}
The parse method you're supposed to be returning the data after doing whatever necessary parsing is required for it.
The common use case for parse would be if you're sending back an object of a form like:
{ "id" : "NaN", "tasks": [ *all your models in a list here *] }
then you'd use parse like so:
parse: function (data) {
return data.tasks
}
Backbone then handles the rest.
Is there a particular reason why you're sending the data back in that dictionary format? It's not exactly clear how you intend to map that to each model of the collection. Is the key irrelevant? if so, you should be passing back a list of the objects in the values.(Although see note at bottom). If not, and you want to attach it to the models, it should be moved to the object you're using as a value and send back a list.
* Note: Don't actually send back a JSON list bare. There is an exploit for GET requests that relies on lists being valid javascript on their own, where a malicious site can use the Array object and override it to use a script tag to your API to use the users credentials to pull down whatever information is available in that call. Instead, when wanting to send back a list you should use something like this:
{ result: [*list here*] }
Then you just use the parse method above to extract the list.

Categories