Accessing data from Angular service with a method - javascript

I am trying to access data from a method within a service which returns coordinates which I use to make an HTTP requests. I added my Leaflet code inside of my controller so I can access that lat,lng coordinates to make an API request to another API. Everything is working. The problem is when I try to pass this data to the controller it does not read the property "L.Control.Search". I also attempted to write an array and access it within the controller and it returned undefined.
app.service('mapService', (function($http,$q) {
//Coordinates
var fmCoordinates = {};
//Function to Request markets
var requestMarkets = function(lat,lng){
var defer = $q.defer();
var dataFromHttp = {};
var options = {
type: "GET",
contentType: "application/json; charset=utf-8",
url: "http://someurl?lat=" + lat + "&lng=" + lng
};
$http(options).then(function(result) {
dataFromHttp = result.data;
defer.resolve(dataFromHttp);
}, function(error){
defer.reject(error);
});
return defer.promise;
};
L.Control.Search = L.Control.extend({
_getLocation: function(key) { //extract latlng from _recordsCache
var latLong = this._recordsCache[key];
console.log("This is latlong:\n"+Object.keys(latLong));
fmCoordinates.lat = latLong.lat;
fmCoordinates.lng = latLong.lng;
console.log(fmCoordinates.lat,fmCoordinates.lng || "Nothing yet!");
var promise = requestMarkets(fmCoordinates.lat,fmCoordinates.lng);
promise.then(function(greeting) {
for(var property in greeting.results) {
console.log(property + "=" + greeting.results[property]);
};
console.log('Success: ' + greeting.results);
}, function(reason) {
console.log('Failed: ' + reason);
});
if( this._recordsCache.hasOwnProperty(key) )
return latLong;//then after use .loc attribute
else
return false;
},
L.Map.addInitHook(function () {
if (this.options.searchControl) {
this.searchControl = L.control.search(this.options.searchControl);
this.addControl(this.searchControl);
}
});
L.control.search = function (options) {
return new L.Control.Search(options);
};
}));

I think your promise code is off slightly. Try changing it to the following. Right now you're returning before the promise has been resolved.
var requestMarkets = function(lat,lng){
var defer = $q.defer();
var dataFromHttp = {};
var options = {
type: "GET",
contentType: "application/json; charset=utf-8",
url: "http://someurl?lat=" + lat + "&lng=" + lng
};
return $http(options).then(function(result) {
dataFromHttp = result.data;
defer.resolve(dataFromHttp);
return defer.promise;
}, function(error){
defer.reject(error);
return defer.promise;
});
};
Also in one place you have l.Control.Search and L.control.search in another.

Related

How to "Promise" (or callback) this code

I have 2 lists in my Sharepoint : speeches and schools.
In my speeches form, I have a school field. I want to autocomplete this field with values (name, adress, city) from schools list.
Here's my code :
$(School_fieldID).autocomplete({
minLength: 2,
source: function (request, response) {
var term = request.term.replace(/ /g, "*\",\"*");
var searchUrl = _spPageContextInfo.webAbsoluteUrl + "/_api/search/query?querytext='and(\"*" + term + "*\",path:\"" + _spPageContextInfo.webAbsoluteUrl + "/Lists/Schools\")'&enablefql=true";
var executor = new SP.RequestExecutor(_spPageContextInfo.webAbsoluteUrl);
executor.executeAsync({
url: searchUrl,
method: "GET",
headers: { "Accept": "application/json; odata=verbose" },
success: function (data) {
var jsonObject = JSON.parse(data.body);
var results = jsonObject.d.query.PrimaryQueryResult.RelevantResults.Table.Rows.results;
var clientContext = new SP.ClientContext();
var schoolList = clientContext.get_web().get_lists().getByTitle('Schools');
response($.map(results, function (result) {
school = schoolList.getItemById(result.Cells.results[6].Value.split('=').pop());
clientContext.load(school, 'Title', 'Adress', 'City');
clientContext.executeQueryAsync(Function.createDelegate(this, function (schoolName, schoolAdress, schoolCity) {
schoolName = school.get_item('Title');
schoolAdress = school.get_item('Adress');
schoolCity = school.get_item('City');
}), Function.createDelegate(this, function (sender, args) {
alert('Error occured: ' + args.get_message());
}));
return {
label: schoolName + " (" + schoolAdress + " " + /*schoolCity + */ ")",
value: schoolName
};
}));
}
});
}
});
When I test this code, schoolName, schoolAdress et schoolCity are undefined because of asynchronous function executeQueryAsync.
So I think solution is in Promise or Callback, but I tried different solutions for a week, without success :-(
Please note I read carefully this post How do I return the response from an asynchronous call?, but can't find a good solution anyway...
Can anyone help me ?
Thanks in advance,
Florent
Considering you have to pass an array of objects to the response callback function and each one of the result is calling the async function clientContext.executeQueryAsync we can turn each one of them into a promise and pass them to Promise.all() which will wait for all of them to be resolved and returned them.
When they are all resolved, the objects will be inside the schoolObjectArray which then you can pass to the response function.
Is should work.
$(School_fieldID).autocomplete({
minLength: 2,
source: function (request, response) {
var term = request.term.replace(/ /g, "*\",\"*");
var searchUrl = _spPageContextInfo.webAbsoluteUrl + "/_api/search/query?querytext='and(\"*" + term + "*\",path:\"" + _spPageContextInfo.webAbsoluteUrl + "/Lists/Schools\")'&enablefql=true";
var executor = new SP.RequestExecutor(_spPageContextInfo.webAbsoluteUrl);
executor.executeAsync({
url: searchUrl,
method: "GET",
headers: { "Accept": "application/json; odata=verbose" },
success: function (data) {
var jsonObject = JSON.parse(data.body);
var results = jsonObject.d.query.PrimaryQueryResult.RelevantResults.Table.Rows.results;
var clientContext = new SP.ClientContext();
var schoolList = clientContext.get_web().get_lists().getByTitle('Schools');
Promise.all($.map(results, function (result) {
school = schoolList.getItemById(result.Cells.results[6].Value.split('=').pop());
clientContext.load(school, 'Title', 'Adress', 'City');
return new Promise(function(resolve,reject) {
clientContext.executeQueryAsync(Function.createDelegate(this, function (schoolName, schoolAdress, schoolCity) {
schoolName = school.get_item('Title');
schoolAdress = school.get_item('Adress');
schoolCity = school.get_item('City');
resolve({
label: schoolName + " (" + schoolAdress + " " + /*schoolCity + */ ")",
value: schoolName
});
}), Function.createDelegate(this, function (sender, args) {
reject('Error occured: ' + args.get_message());
}));
})
}))
.then(function(schoolObjectArray){
response(schoolObjectArray)
})
.catch(console.error);
}
});
}
});

script for window.location.href error

this Q. is a continue of this question first qestion I have a form that I need to redirect to action with the form uploaded details (just like In stackoverflow) , but apparently because i'm using Ajax , it prevent it from redirect , I have tried to add my Ajax a redirect but I keep getting error and wrong Url . it should redirect from http://localhost:1914/En/VoosUp/Create To http://localhost:1914/En/events/Index/42 (E.G. Id number) the results i'm getting with what I wrote are in my Js Code
How can I redirect it to the correct url (Events/Index/Id )
Thanks in advance
Js
function GetLocation() {
var geocoder = new window.google.maps.Geocoder();
var street = document.getElementById('txtAddress').value;
var city = document.getElementById('txtCity').value;
var address = city + street;
console.log(address);
var labelLat = document.getElementById('Latitude');
var labellong = document.getElementById('longitude');
geocoder.geocode({ 'address': address },
function(results, status) {
if (status == window.google.maps.GeocoderStatus.OK) {
var latitude = results[0].geometry.location.lat();
var longitude = results[0].geometry.location.lng();
console.log("Latitude: " + latitude + "\nLongitude: " + longitude); //Ok.
labelLat.value = latitude; //Ok.
labellong.value = longitude;
var form = $('#RestoForm')[0];
var formData = new FormData(form);
$.ajax({
url: 'Create',
type: 'POST',
contentType: false,
processData: false,
data: formData,
datatype: "html",
success: function(data) {
$('#RestoForm').html(data),
// window.location.href = '#Url.Content:("~/Events/Index")' + "Id";
//= A potentially dangerous Request.Path value was detected from the client (:).
// En/VoosUp/#Url.Content:("~/Events/Index")Id
window.location.href = '#Url.Action("~/Events/Index")';
// =The resource cannot be found >
//En/VoosUp/#Url.Action("Events/Index
}
});
error: function e(xhr, ajaxOptions, thrownError) {
alert(xhr.status);
alert(thrownError);
}
}
});
};`
Controller:
[Authorize]
public ActionResult Create()
{
var viewModel = new LectureFormViewModel
{
Genres = _context.Genres.ToList(),
};
return View("Gigform", viewModel);
}
[Authorize, HttpPost]
public ActionResult Create(LectureFormViewModel viewModel)
{
if (!ModelState.IsValid)
{
viewModel.Genres = _context.Genres.ToList();
return View("Gigform", viewModel);
}
var lectureGig = new LectureGig
{
//Parameters
};
_context.LectureGigs.Add(lectureGig);
_context.SaveChanges();
// return this.RedirectToAction( "events", (c=>c.Index(lectureGig.Id));
return RedirectToAction("index", "Events", new { id = lectureGig.Id });
}
and the target
public ActionResult Index(int id)
{
var lecturegig = _context.LectureGigs.Include(g => g.Artist)
.Include(g => g.Genre)
.SingleOrDefault(g => g.Id == id);
if (lecturegig == null)
return HttpNotFound();
var viewmodel = new GigDetailViewModel { LectureGig = lecturegig };
return View("index", viewmodel);
}
This should do it if your JavaScript is in the cshtml:
var id = 1;
var url = '#Url.Action("Index", "Events")';
window.location.href = url + "/" + id;
Based on your description however it seems that you are trying to call this from a .js file which has no idea about MVC helpers so instead you can try something like this:
var id = 1;
var getUrl = window.location;
var baseUrl = getUrl.protocol + "//" + getUrl.host + "/" + getUrl.pathname.split('/')[1];
window.location.href = baseUrl + '/Events/Index' + id;
To get the correct Id modify your action to return the Id e.g.
public JsonResult Create(LectureFormViewModel viewModel)
{
return Json(new { Id=lectureGig.Id });
}
then you can access this Id in JavaScript e.g.
success: function(data) {
var id = data.Id;
}
If it is in a cshtml file you can use the code
window.location.href = '#Url.Action("Index", "Events")'+ "?id=1";
If you are in js file
window.location.href='/Events/Index?id=1'

Getting an 'undefined' error when working with my factory in my controller

Hey guys I'm working on a new app, but I ran into a road block. My factory works fine within it self, but when I try to use it in my controller I get:
Error: getPlaces.getPlaces(...) is undefined
Here the code in my factory:
angular.module('Space')
.factory('getPlaces', ['$http', function($http) {
var placesFactory = {};
placesFactory.getPlaces = function() {
if (navigator.geolocation) {
var geoLoc = navigator.geolocation;
return geoLoc.getCurrentPosition(function(position) {
var lat = position.coords.latitude,
lng = position.coords.longitude;
return getFSinfo(lat, lng);
});
} else {
alert('Opps. Looks like you have your location turned off. Space uses your location to find places near you.');
}
function getFSinfo (lat, lng) {
var clientID = 'J2HCJIGLTSFFJMKMLAEBT30QNLINBSDQBBDZNRRH1MUSDZ4V',
clientSercet = 'RJBO0O01D2OSPR5R2KF4S214CFNXAOAD03DJM3L15ERLUCXF',
coords = lat + ',' + lng,
searchIds = '';
var categoryIds = {
movie: '4bf58dd8d48988d17f941735',
museum: '4bf58dd8d48988d181941735',
stadium: '4bf58dd8d48988d184941735',
themePark: '4bf58dd8d48988d182941735',
waterPark: '4bf58dd8d48988d193941735',
eventVenue: '4d4b7105d754a06373d81259',
food: '4d4b7105d754a06374d81259',
mall: '4bf58dd8d48988d1fd941735',
musicStore: '4bf58dd8d48988d1fe941735',
foodDrink: '4bf58dd8d48988d1f9941735',
clothesStore: '4bf58dd8d48988d103951735'
};
for (var key in categoryIds) {
searchIds += categoryIds[key] + ',';
}
var FSUrl = 'https://api.foursquare.com/v2/venues/search?ll=' + coords + '&client_id=' + clientID + '&client_secret=' +
clientSercet +'&intent=browse&radius=20000' + '&categoryId=' + searchIds + '&v=20130815' + '&limit=50';
return $http.get(FSUrl)
.then(function(response) {
var data = response.data.response;
console.log(data);
return data;
}, function(error) {
console.log(error);
});
}
};
return placesFactory;
}]);
Controller:
angular.module('Space')
.controller('MainCtrl', ['getPlaces', '$http', function(getPlaces, $http) {
var vm = this;
vm.message = 'Hello world!';
getPlaces.getPlaces().then(function(data) {
vm.place = data;
console.log(vm.place);
});
}]);
I don't understand why thought.
Any help would be great!
Your controller is expecting getPlaces() to return a promise. getCurrentPosition() does not return anything. You can create your own promise though like this:
if (navigator.geolocation) {
var geoLoc = navigator.geolocation;
return $q(function(resolve) {
geoLoc.getCurrentPosition(function(position) {
var lat = position.coords.latitude,
lng = position.coords.longitude;
resolve(getFSinfo(lat, lng));
});
});
}
Be sure to inject $q into the factory. Lastly, to use $q as I have, you'll need Angular 1.3+. If you're using an earlier version, you can accomplish the same thing with deferreds.

Creating a jQuery plugin with getJSON inside the function

I am not sure if this is due to the fact that getJSON is asynchronous or not. I think that would be the most obvious reason, but I don't have a clear understanding of how that works. In my js file, I call the healthCheck method on the body element. Nothing happens. Is my getJSON callback function even getting called? I don't know.
I have uploaded the script on JSFiddle.
The code is also below:
var baseURL = "http://someURL";
var id = "00000001";
var key = "0000aaaa-aa00-00a0-a00a-0000000a0000";
var healthcheck = "/version/healthcheck?";
( function($) {
$.fn.healthCheck = function() {
var timestamp = new Date().toJSON().toString();
var request = healthcheck + "timestamp=" + timestamp + "&devid=" + id;
var signature = CryptoJS.HmacSHA1(request, key);
request = baseURL + request + "&signature=" + signature;
$.getJSON(request, function(data) {
var result = new Object();
$.each(data, function(key, val) {
result.key = val;
if (val == false) {
this.innerHTML = "PTV API is currently not working. Error type: " + key + ".";
} else {
this.append(key + " working. <br />");
}
});
});
return this;
};
}(jQuery));
Many thanks in advance. I hope my query is well placed. If anyone knows some good resources to get a better understanding of asynchronous methods in jQuery that would be greatly appreciated, also. I haven't found many that have been easy to follow yet.
Try 1) setting context of jQuery.ajax( url [, settings ] ) to this of $.fn.healthCheck ; 2) create reference to this object at $.each()
var baseURL = "http://someURL";
var id = "00000001";
var key = "0000aaaa-aa00-00a0-a00a-0000000a0000";
var healthcheck = "/version/healthcheck?";
(function($) {
$.fn.healthCheck = function() {
// set `this` object within `$.getJSON`
var timestamp = new Date().toJSON().toString();
var request = healthcheck + "timestamp=" + timestamp + "&devid=" + id;
var signature = CryptoJS.HmacSHA1(request, key);
request = baseURL + request + "&signature=" + signature;
$.ajax({
url:request
, type:"GET"
, contentType: false
, context: this
, processData:false
}).then(function(data) {
// reference to `this` within `$.each()`
var that = this;
var result = new Object();
$.each(JSON.parse(data), function(key, val) {
result.key = val;
if (val == false) {
// `that` : `this`
that.innerHTML = "PTV API is currently not working. Error type: " + key + ".";
} else {
that.append(key + " working. <br />");
console.log("complete"); // notification
}
});
}, function(jqxhr, textStatus, errorThrown) {
console.log(textStatus, errorThrown); // log errors
});
return this;
};
}(jQuery));
$("body").healthCheck();
See also How do I return the response from an asynchronous call?
var baseURL = "https://gist.githubusercontent.com/guest271314/23e61e522a14d45a35e1/raw/62775b7420f8df6b3d83244270d26495e40a1e9d/a.json";
var id = "00000001";
var key = "0000aaaa-aa00-00a0-a00a-0000000a0000";
var healthcheck = "/version/healthcheck?";
(function($) {
$.fn.healthCheck = function() {
var timestamp = new Date().toJSON().toString();
var request = healthcheck + "timestamp=" + timestamp + "&devid=" + id;
var signature = 123;// CryptoJS.HmacSHA1(request, key);
request = baseURL + request + "&signature=" + signature;
$.ajax({
url:request
, type:"GET"
, contentType: false
, context: this
, processData:false
}).then(function(data) {
var that = this;
var result = new Object();
$.each(JSON.parse(data), function(key, val) {
result.key = val;
if (val == false) {
that.innerHTML = "PTV API is currently not working. Error type: " + key + ".";
} else {
that.append(key + " working. <br />");
console.log("complete"); // notification
}
});
}, function(jqxhr, textStatus, errorThrown) {
console.log(textStatus, errorThrown); // log errors
});
return this;
};
}(jQuery));
$("body").healthCheck()
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

Ajax send image to server

I am working phonegap application. I want to send data image to server but i can not sent it.
function addSiteToServer() {
var cId = localStorage.getItem("cId");
var sname = $('#sitename').val();
var slat = $('#lat').val();
var slng = $('#lng').val();
var storedFieldId = JSON.parse(localStorage["field_id_arr"]);
var p = {};
for (var i = 0; i < storedFieldId.length; i++) {
var each_field = storedFieldId[i];
var val_each_field = $('#' + each_field).val();
p[each_field] = val_each_field;
console.log("p" + p);
}
var online = navigator.onLine;
if (online) {
var data = {
site: {
collection_id: cId,
name: sname,
lat: slat,
lng: slng,
properties: p
}
};
//function sending to server
$.ajax({
url: App.URL_SITE + cId + "/sites?auth_token=" + storeToken(),
type: "POST",
data: data,
enctype: 'multipart/form-data',
crossDomain: true,
datatype: 'json',
cache: false,
contentType: false,
processData: false,
success: function(data) {
console.log("data: " + data);
alert("successfully.");
},
}
Looks like you are using the normal method to send data/image to server which is not recommended by Phonegap/Cordova Framework.
I request you to replace your code with the following method which works as you expected,I also used local storage functionality to send values to server,
function sendDataToServer(imageURI) {
var options = new FileUploadOptions();
options.fileKey="file";
options.fileName=imageURI.substr(imageURI.lastIndexOf('/')+1);
options.mimeType="image/jpeg";
var params = {};
params.some_text = localStorage.getItem("some_text");
params.some_id = localStorage.getItem("some_id");
params.someother_id = localStorage.getItem("someother_id");
options.params = params;
var ft = new FileTransfer();
ft.upload(imageURI, encodeURI("http://example.co.uk/phonegap/receiveData.php"), win, fail, options);
}
function win(r) {
console.log("Code = " + r.responseCode+"Response = " + r.response+"Sent = " + r.bytesSent);
}
function fail(error) {
alert("An error has occurred: Code = " + error.code);
}
function saveData(){
sendDataToServer(globalvariable.imageURI);
alert("Data Saved Successfully");
}
Hope this helps.

Categories

Resources