Bind to AngularJS Service property - angularjs

I have a web page which uses a custom service to manage a map on the View (OpenLayers). I want to be able to display information about different markers on the page somewhere which means binding to a service property. The service is being called from a custom directive, and the binding (as far as I know) should be done from the Controller. The data being shown at the moment is the initialised object rather than binding to any changes to that object.
main.html
<h2>My Map</h2>
<div id="map" class="map"></div>
<p>
Name: {{selected.name}}</br>
Routers: {{selected.routers}}</br>
Switches: {{selected.switches}}
</p>
main.ctrl.js
angular.module("app").controller("MainController", function($scope, openlayers){
openlayers.init();
$scope.selected = openlayers.selected;
});
openlayers.js
angular.module("app").factory("openlayers", function(){
var init = function(){
var vectorLayers = [new ol.layer.Tile({
source: new ol.source.MapQuest({layer: 'osm'})
})];
vectorLayers.push(createMapLayer("red"));
vectorLayers.push(createMapLayer("orange"));
vectorLayers.push(createMapLayer("blue"));
setUpMap(vectorLayers);
};
var activeVector = {
name: null,
routers: null,
switches: null
};
function createMapLayer(markerColor){
var vectorSource = getVectorSource();
//add the feature vector to the layer vector, and apply a style to whole layer
var vectorLayer = new ol.layer.Vector({
source: getVectorSource(cities[markerColor]),
style: getIconStyle(markerColor)
});
return vectorLayer;
}
function getVectorSource(cities){
var vectorSource = new ol.source.Vector({
//create empty vector
});
//create a bunch of icons and add to source vector
for (var index in cities){
var city = cities[index];
var iconFeature = new ol.Feature({
geometry: new ol.geom.Point(
ol.proj.transform(
[city.lon, city.lat],
'EPSG:4326',
'EPSG:3857'
)),
name: city.name,
routers: 200,
switches: 100
});
vectorSource.addFeature(iconFeature);
}
return vectorSource;
}
function getIconStyle(markerColor){
//create the style
return new ol.style.Style({
image: new ol.style.Icon(/** #type {olx.style.IconOptions} */ ({
anchor: [0.5, 46],
anchorXUnits: 'fraction',
anchorYUnits: 'pixels',
opacity: 0.75,
src: "Images/"+markerColor+"-marker.png"
}))
});
}
function setUpMap(vectorLayers){
var map = new ol.Map({
target: 'map',
layers: vectorLayers,
view: new ol.View({
center: ol.proj.fromLonLat([2.808981, 46.609599]),
zoom: 4
})
});
addClickEventsToMapItems(map);
}
function addClickEventsToMapItems(map){
var interaction = new ol.interaction.Select({
condition: ol.events.condition.click
});
map.addInteraction(interaction);
interaction.on("select", function(e){
activeVector.name = e.target.getFeatures().item(0).get("name");
activeVector.routers = e.target.getFeatures().item(0).get("routers");
activeVector.switches = e.target.getFeatures().item(0).get("switches");
});
}
return {
init: init,
selected: activeVector
};
});
var red_cities = [
{ "lat": 40.462663, "lon": -3.626368, "name": "madrid" },
{ "lat": 53.381129, "lon": -1.470085, "name": "sheffield" },
{ "lat": 48.856614, "lon": 2.352222, "name": "paris" }
];
var orange_cities = [
{ "lat": 53.480759, "lon": -2.242631, "name": "manchester" },
{ "lat": 53.551085, "lon": 9.993682, "name": "hamburg" },
{ "lat": 50.850340, "lon": 4.351710, "name": "brussels" }
];
var blue_cities = [
{ "lat": 43.552847, "lon": 7.017369, "name": "cannes" },
{ "lat": 51.507351, "lon": -0.127758, "name": "london" },
{ "lat": 52.370216, "lon": 4.895168, "name": "amsterdam" },
{ "lat": 36.140751, "lon": -5.353585, "name": "gibraltar" }
];
var cities = {
red: red_cities,
orange: orange_cities,
blue: blue_cities
};
EDIT: Removed the directive to simplify the code.

Related

JSON conversion issue when returning data from Firebase using angular

I am retrieving data from Firebase and when I convert to JSON like this:
$scope.array.push(angular.toJson(obj));
I get this:
["{ "lat": "50", "lon": "3", "title": "my title", "content": "my content" }"]
How do I convert it so that I get this:
[{ "lat": "50", "lon": "3", "title": "my title", "content": "my content"}]
In my angular directive I see the data when I console.log it and it appears like this:
[]
0: "{ "lat": "50", "lon": "3", "title": "my title", "content": "my content" }"
In order to get the data from Firebase, if I do $scope.array.push(obj); I get this:
[]
0 {key : "value"}
So in order to get my code to run I need the 'key' in quotes too.
The other issue I'm having is that the link function in my directive is running before the data is returned in the scope.arrLocations variable. There is a watch that I expected to pick up changes to this variable. So I was expecting that when I got the data formatted properly it would just work.
Here's my code in full:
app.factory('map', ['$q', function($q){
var map={};
var mapInfoItems=[];
map.getMapInfo = function() {
var deferred = $q.defer();
var mapitems = firebase.database().ref('mapinfo/'+firebase.auth().currentUser.uid);
mapitems.on('child_added', function(snapshot){
mapInfoItems.push(snapshot.val());
deferred.resolve(mapInfoItems);
});
//return mapInfoItems;
return deferred.promise;
};
return map;
}]);
app.controller('mapController', ['$scope', 'map', function($scope, map){
$scope.myLocations = {};
$scope.arrLocations = [];
var allLocations = [];
//$scope.arrLocations = [ { "lat": "50", "lon": "3", "title": "my title", "content": "my content" }];
$scope.mapLocations = map.getMapInfo();
map.getMapInfo().then(function(locations){
for(var i=0; i<locations.length; i++){
// create new object each iteration
var obj ={
title : locations[i].name,
content: locations[i].message,
lat : locations[i].lat,
lon : locations[i].lon
}
allLocations.push(obj);
}
$scope.arrLocations = allLocations;
});
}]);
app.directive('myMap', [function() {
// directive link function
var link = function(scope, element, attrs) {
//console.log(scope.myLocations);
console.log('in the link function');
//the line below works and the marker is shown on the map
//scope.arrLocations = [ { "lat": "50", "lon": "3", "title": "my title", "content": "my content" }];
//console.log(scope.arrLocations);
var map, infoWindow;
var markers = [];
//var lastElement = '';
// map config
var mapOptions = {
// center: new google.maps.LatLng(50, 3),
center: new google.maps.LatLng(scope.lastElement.lat, scope.lastElement.lon),
zoom: 10,
mapTypeId: google.maps.MapTypeId.ROADMAP,
scrollwheel: true
};
// init the map
function initMap() {
if (map === void 0) {
map = new google.maps.Map(element[0], mapOptions);
}
}
// place a marker
function setMarker(map, position, title, content) {
var marker;
var markerOptions = {
position: position,
map: map,
title: title,
icon: 'https://maps.google.com/mapfiles/ms/icons/green-dot.png'
};
marker = new google.maps.Marker(markerOptions);
markers.push(marker); // add marker to array
google.maps.event.addListener(marker, 'click', function () {
// close window if not undefined
if (infoWindow !== void 0) {
infoWindow.close();
}
// create new window
var infoWindowOptions = {
content: content
};
infoWindow = new google.maps.InfoWindow(infoWindowOptions);
infoWindow.open(map, marker);
});
}
scope.$watch(function() { return scope.arrLocations; }, function() {
initMap();
console.log(scope.arrLocations);
scope.lastElement = scope.arrLocations[scope.arrLocations.length - 1];
// clear markers
for (var i = 0; i < markers.length; i++) {
markers[i].setMap(null);
}
markers = [];
angular.forEach(scope.arrLocations, function(value, key){
//console.log('value: ' + value + ' | key: ' + key);
// a single object in this example could be:
// { lat: 50, lon: 3, title: "my title", content: "my content" }
var location = new google.maps.LatLng(value.lat, value.lon);
setMarker(map, location, value.title, value.content);
});
});
};
return {
restrict: 'EA',
//scope: {getMapFn: '&'},
template: '<div id="gmaps"></div>',
replace: true,
link: link
};
}]);
Don't stringify the object...just push the object itself to array
Change:
$scope.array.push(angular.toJson(obj));
To
$scope.array.push(obj);
As for the console log of length it sounds like you are trying to check length before data has been pushed into the array. Most likely before the data request has been received
Gave up using my existing code. Decided to use this instead.

How to fetch data from json in angularjs Form

How to call the data from json in angularjs form without using backend. i have written this code and here m unable to find a way in last to get data from the json file. someone please help me to move forward from here.
code
$scope.count = $scope.newPreAuth.length;
};
//Delete newPreAuth - Using AngularJS splice to remove the preAuth row from the newPreAuth list
//All the Update newPreAuth to update the locally stored newPreAuth List
//Update the Count
$scope.deletenewPreAuth = function (preAuth) {
$scope.newPreAuth.splice($scope.newPreAuth.indexOf(preAuth), 1);
getLocalStorage.updatenewPreAuth($scope.newPreAuth);
$scope.count = $scope.newPreAuth.length;
};
}]);
//Create the Storage Service Module
//Create getLocalStorage service to access UpdateEmployees and getEmployees method
var storageService = angular.module('storageService', []);
storageService.factory('getLocalStorage', function () {
var newPreAuthList = {};
return {
list: newPreAuthList,
updatenewPreAuth: function (newPreAuthArr) {
if (window.localStorage && newPreAuthArr) {
//Local Storage to add Data
localStorage.setItem("newPreAuth", angular.toJson(newPreAuthArr));
}
newPreAuthList = newPreAuthArr;
},
getnewPreAuth: function () {
//Get data from Local Storage
newPreAuthList = angular.fromJson(localStorage.getItem("newPreAuth"));
return newPreAuthList ? newPreAuthList : [];
}
};
});
Json Code
PreAuth:
======================
URL:http://dev.xxx.com:8080/xxx/preAuth
TYPE:POST
X-Auth-Token t3Z10HGEiYFdzq9lGtr18ycdeAAXmWBEI64rQAJcAte6Ka8Tz96IAhuXHSgpiKufsd
{
"preAuth": {
"claimbId": "newPreAuth",
"claimbStatus": "new",
"patientInfo": {
"patientName": "name",
"gender": "Male",
"dob": 950639400000,
"age": 21,
"contactNumber": 9987654356,
"tpaMemberId": 950639400121,
"policyNumber": "ABC12615627",
"corporateName": "ABC",
"EmployeeId": "XYZ10232",
"otherInsurance": {
"isOtherInsurance": true,
"playerName": "xyx",
"details": "sdfdsafdsfdsf"
},
"familyPhysician": {
"isFamilyPhysician": true,
"physicianName": "fsdf"'c
"physicianContactNumber": 7878748728,
"address": {
"address1": "Hosa road",
"address2": "Basapura",
"city": "Bangalore",
"state": "Karnataka",
"country": "India",
"pincode": "560100"
}
},
"isFamilyPhysician": false,
"address": {
"address1": "Hosa road",
"address2": "Basapura",
"city": "Bangalore",
"state": "Karnataka",
"country": "India",
"pincode": "560100"
}
},
"medicalInfo": {
"illnessType": "cancer",
"clinicalFinding": "description",
"ailmentDuration": "2 months",
"ailmentHistory": "description",
"illnessCause": "alcohol",
"provisionalDiagnosis": [
{
"diagnosisName": "abc",
"diagnosisICDCode": "121423"
},
{
"diagnosisName": "xyz",
"diagnosisICDCode": "434543"
}
],
"differentialDiagnosis": [
{
"diagnosisName": "afasdbc",
"diagnosisICDCode": "12431423"
},
{
"diagnosisName": "fdxyz",
"diagnosisICDCode": "434sdf543"
}
],
"clinicalObservations": {
"BP": "120/80",
"CVS": "126",
"P.A.": "abc",
"R.S.": "aa",
"CNS": "dd",
"others": "others"
},
"maternityDetails": {
"maternityType": "G",
"L.M.P.": 950639400000,
"E.D.D.": 950639400000
},
"accidentDetails": {
"accidentCause": "xyz",
"accidentDate": 950639400000,
"isPoliceComplaint": true,
"firNumber": "asfsafds"
},
"pastIllness": [
{
"pastIllnessType": "Diabetes",
"isPresent": true,
"NoOfMonth": 2,
"NoOfYear": 5,
"illnessSince": 950639400000
},
{
"pastIllnessType": "Hypertension",
"isPresent": true,
"NoOfMonth": 2,
"NoOfYear": 5,
"illnessSince": 950639400000
},
{
"pastIllnessType": "Other",
"isPresent": false,
"NoOfMonth": 2,
"NoOfYear": 5,
"illnessSince": 950639400000
}
]
},
"treatmentInfo": {},
"billingInfo": {},
"documents": [
{
"documentId": 12345,
"documentMetadata": {
"documentName": "discharge summary",
"date": 950639400000,
"version": "1.1",
"viewedStatus": false,
"link": "link to view/download document"
}
},
{
"documentId": 12346,
"documentMetadata": {
"documentName": "medical summary",
"date": 950639400000,
"version": "1.0",
"viewedStatus": true,
"link": "link to view/download document"
}
}
]
}
}
I created sample ,it worked this way
// Code goes here
var app = angular.module('app',[]);
app.controller('sample', function($scope,$http){
$scope.name = "advaitha";
$http.get('test.json').then(function(data){
console.log(data.data);
});
})
here is the plunker example
using HTML5 localStorage would require you to serialize and deserialize your objects before using or saving them.
For example:
var myObj = {
firstname: "kisun",
lastname: "rajot",
website: "https://www.kisun.com"
}
//if you wanted to save into localStorage, serialize it
window.localStorage.set("empData", JSON.stringify(myObj));
//unserialize to get object
var myObj = JSON.parse(window.localStorage.get("empData"));
Created a plunker based on your code am able save and retrieve the json data with your code. Please check here

mapbox-gl.js with PGRestAPI vector tile(pbf)

I have own vector tile from PGRestAPI, url like below
"http://192.168.1.4:3001/services/postgis/cleantech2/geom/vector-tiles/{z}/{x}/{y}.pbf"
and I try use mapbox-gl.js to render the map, but nothing display.
I am doing wrong? thx
var style = {
"version": 8,
"sources": {
"countries": {
"type": "vector",
"tiles": ["http://192.168.1.4:3001/services/postgis/cleantech2/geom/vector-tiles/{z}/{x}/{y}.pbf"],
"maxzoom": 6
}
},
"glyphs": location.origin+location.pathname+"font/{fontstack}/{range}.pbf",
"layers": [{
"id": "background",
"type": "background",
"paint": {
"background-color": "#ddeeff"
}
},{
"id": "country-glow-outer",
"type": "line",
"source": "countries",
"source-layer": "country",
"layout": {
"line-join":"round"
}
}]
};
var init_lat = 1.3552799//42.299228067198634;
var init_lng = 103.6945413;//-83.69717033229782;
mapboxgl.accessToken = 'mapbox-token';
var map = new mapboxgl.Map({
container: 'map',
style: style,
center: [init_lng,init_lat],
zoom: 15
});
edit 1:
after debug mapbox-gl-js code, now can see several circles. I modify the style, the source-layer name from pbf must be correct.
but not display all the points, it seems filtered?
var style = {
"version": 8,
"sources": {
"cleantech": {
"type": "vector",
// "url": "mapbox://map-id"
// "url": "http://tileserver.com/layer.json",
"tiles": ["http://192.168.1.4:3001/services/postgis/cleantech2/geom/vector-tiles/{z}/{x}/{y}.pbf"],
"maxzoom": 6
}
},
"glyphs": location.origin+location.pathname+"font/{fontstack}/{range}.pbf",
"layers": [{
"id": "cleantech2_geom_id",
"type": "circle",
'source': 'cleantech',
'layout': {
'visibility': 'visible'
},
'paint': {
'circle-radius': 8,
'circle-color': 'rgba(55,148,179,1)'
},
'source-layer': 'cleantech2_geom'
}]
};
edit 2:
change the maxzoom to 22, all data displayed. lets drink!

Error in routing with id parameter, link works but displays no data

I am having an issue with retrieving the stored data (within MongoDB) by way of an :id parameter. The link works and takes me to the specified url (./contests/1), but the data doesn't show up. When querying within the mongo CMD with (db.contests.find( {id:1} )) the correct object's data is displayed correctly.
route/contest.js
router.route("/contests/:id")
.get(function(req, res, next) {
Contest.findOne({id: req.params.id}, function(err, contest) {
if(err) {
res.send(err);
}
res.json(contest);
});
service/contestService.js
app.factory("contestService", ["$http", "$resource",
function($http, $resource)
{
var o = {
contests: []
};
function getAll() {
return $http.get("/contests").then(function(res) {
angular.copy(res.data, o.contests);
});
}
function get(id) {
return $resource('/contests/:id');
}
o.getAll = getAll;
o.get = get;
return o;
}]);
})();
controller/contestController.js
var app = angular.module("sportsApp.controllers.contest,["ui.router"]);
app.config(["$stateProvider", function($stateProvider) {
$stateProvider.state("contest", {
parent: "root",
url: "/contests/:id",
views: {
"container#": {
templateUrl: "partials/contests",
controller: "ContestController"
}
}
});
}
]);
app.controller("ContestController", ["$scope","contestService", "$stateParams", function($scope, contestService, $stateParams) {
var contest_id = $stateParams.id;
$scope.contest = contestService.get({id: contest_id});
}]);
})();
Contest Schema
var mongoose = require("mongoose");
var ContestSchema = new mongoose.Schema(
{
id: Number,
tags: String,
matchups: [{
type: mongoose.Schema.Types.ObjectId,
ref: "Matchup"
}],
usersWhoJoined: [{
type: mongoose.Schema.Types.ObjectId,
ref: "User"
}]
});
mongoose.model("Contest", ContestSchema);
Any assistance or advice would be much appreciated due to the fact that I am learning as I go with the MEAN stack and have little to no experience with it.
I am looking to display the specific contest's matchups in which displays two teams and other variables. This is my json file that I mongoimported in order to create the object of the contests collection within MongoDB:
{
"id": 1,
"tags": "NBA",
"matchups": [{
"matchupId": 1,
"selectedTeam": "",
"matchupWinner": "Atlanta",
"nbaTeams": [{
"team": "Portland",
"logo": "stylesheets/nbalogos/Portland-Trail-Blazers-Logo.png"
}, {
"team": "Atlanta",
"logo": "stylesheets/nbalogos/atl-hawks.png"
}]
}, {
"matchupId": 2,
"selectedTeam": "",
"matchupWinner": "Dallas",
"nbaTeams": [{
"team": "Dallas",
"logo": "stylesheets/nbalogos/Dallas-Mavericks.png"
}, {
"team": "Detroit",
"logo": "stylesheets/nbalogos/DET.png"
}]
}, {
"matchupId": 3,
"selectedTeam": "",
"matchupWinner": "Golden State",
"nbaTeams": [{
"team": "Golden State",
"logo": "stylesheets/nbalogos/GSW.png"
}, {
"team": "Memphis",
"logo": "stylesheets/nbalogos/Memphis-Grizzlies.png"
}]
}, {
"matchupId": 4,
"selectedTeam": "",
"matchupWinner": "Oklahoma City",
"nbaTeams": [{
"team": "Oklahoma City",
"logo": "stylesheets/nbalogos/OKC-Thunder.png"
}, {
"team": "Pheonix",
"logo": "stylesheets/nbalogos/Pheonix-Suns.jpg"
}]
}, {
"matchupId": 5,
"selectedTeam": "",
"matchupWinner": "Utah",
"nbaTeams": [{
"team": "Sacremento",
"logo": "stylesheets/nbalogos/Sacremento-Kings.jpg"
}, {
"team": "Utah",
"logo": "stylesheets/nbalogos/Utah-Jazz.jpg"
}]
}]
}
I want to create each contest in this format.
I have no idea what relevance the actual data has to this issue, so let's start with $scope.contest, since there seems to be a problem with the way you're accessing data.
// ContestController
$scope.contest = contestService.get({id: contest_id});
OK, so you're calling the contestService.get method with an object, let's say it's {id: 2}. Let's look at that method and call it with that object.
// contestService
function get(id) {
return $resource('/contests/' + id);
}
If using our dummy data, if you call get({id: 2}), you now have an Angular resource at the URL /contests/[object Object] because your object gets converted into a string. Your method would work if called using the value at the id property of that object, like:
// ContestController
$scope.contest = contestService.get(contest_id);

Angular-Leaflet-Directive + JSON markers

Try create Leaflet Map with clustering markers in my app. Using for this Angular Leaflet Directive plugin.
It's work with example controller and JSON data, but I have other JSON with other data format and have problem with get lattitude and longitude parameters for creating markers array on my map.
My Controller
app.controller("BasicFirstController", [ "$scope", "$http", function($scope, $http) {
var addressPointsToMarkers = function(points) {
return points.map(function(ap) {
return {
layer: 'realworld',
lat: ap[0],
lng: ap[1],
message: ap[2]
};
});
};
angular.extend($scope, {
center: {
lat: 53.13207624721133,
lng: 26.01689853383789,
zoom: 15
},
events: {
map: {
enable: ['moveend', 'popupopen'],
logic: 'emit'
},
marker: {
enable: [],
logic: 'emit'
}
},
layers: {
baselayers: {
osm: {
name: 'OSM',
url: 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
type: 'xyz'
},
overlays: {
realworld: {
name: "Real world data",
type: "markercluster",
visible: true
}
}
}
});
$http.get("sample.json").success(function(data) {
$scope.markers = addressPointsToMarkers(data);
});
}]);
Work with this JSON format
[
[-37.8839, 175.3745188667, "571"],
[-37.8869090667, 175.3657417333, "486"],
[-37.8894207167, 175.4015351167, "807"],
[-37.8927369333, 175.4087452333, "899"],
[-37.90585105, 175.4453463833, "1273"]
]
Need work with this JSON format
{
"posts": [
{
"ID": "1",
"title": "Title",
"tag": "tag1",
"lat": "53.11691211703813",
"lng": "26.03631556034088",
"thumb": "getImage-24-100x100.jpg",
"fullimg": "getImage-24.jpg",
"imgs": [
{
"imgurl": "getImage-24-300x200.jpg"
}
],
"place": "Place",
"type": "Photo",
"period": "War",
"year": "1985",
"url": "site.com",
"author": "author"
},
{
"ID": "2",
"title": "Title2",
"tag": "tag2",
"lat": "53.11691211703813",
"lng": "26.03631556034088",
"thumb": "getImage-24-100x100.jpg",
"fullimg": "getImage-24.jpg",
"imgs": [
{
"imgurl": "getImage-24-300x200.jpg"
}
],
"place": "Place",
"type": "Photo",
"period": "War",
"year": "1935",
"url": "site.com",
"author": "author"
}
]
}
How get data with lat and lng from JSON for markers array?
Here is what worked for me with a JSON file sent from server, to publish ALL markers at once:
Then with $HTTP I can "get" the data, but you will have to loop through it and push details to a new $scope array:
$scope.markers = []
$http.get('JSONfilePath').then(function (responseData) {
for (var i = 0; i < responseData.data.length; i++){
$scope.markers.push({
lat: responseData.data[i].latitude,
lng: responseData.data[i].longitude
})
}
})
In the HTML file, it's pretty straight forward:
<leaflet lf-center="center" defaults="defaults" markers="markers" width="90%" height="800px"></leaflet>

Resources