Google Maps API dynamic load with AngularJS - angularjs

I'm trying to load Google Maps API using AngularJS:
<html data-ng-app="search-app">
<head data-ng-controller="GoogleMaps">
<script ng-src="{{mapsUrl}}" type="text/javascript"></script>
....
</head>
and controller for that part:
search.controller('GoogleMaps', [
'$scope','$sce',
function GoogleMaps($scope,$sce) {
var mapsUrl = '//maps.google.com/maps/api/js?sensor=false&key=my_api_key';
$scope.mapsUrl = $sce.trustAsResourceUrl(mapsUrl);
}
]);
but when the Google Map API is called within the search controller it throws and error
this.setMap is not a function
for
function CustomMarker(latlng, map, args) {
this.latlng = latlng;
this.args = args;
this.setMap(map);
}
but when I will replace {{mapsUrl}} with full URL in the HTML header it will works.
Any thoughts on that?

I have ended up appending URL to the header as a script on load event
function require(url, callback)
{
var element = document.createElement("script");
element.src = url;
element.type="text/javascript";
element.addEventListener('load', callback);
document.getElementsByTagName("head")[0].appendChild(e);
}

Related

Angular $http fails to return coherent cache

I have a problem where a page has two components but only one of them is fully rendered.
The problem seem to be related to $http. I have a angular project where I need to construct a page based on RESTful API. The pages are such that I can expect multiple requests for the same data. At the moment, the set of requests are not behaving correctly.
For the sake of the argument (and also because it is a use case), the following page makes the same request twice.
game.html:
<html ng-app="prvdApp">
<head>
<meta charset="utf-8">
<base href="/">
<title>Providence</title>
<script src="/js/angular-1.6.2.js"></script>
<script src="/data-access/data-access.service.js"></script>
<script src="/score-info/score-info.component.js"></script>
<script src="/js/game.js"></script>
</head>
<body>
<div ng-controller="gameController">
<score-info game-id="8000"></score-info>
<score-info game-id="8000"></score-info>
</div>
</body>
game.js:
angular.module('prvdApp', [
'scoreInfo',
'drivesInfo' ]);
angular.
module('prvdApp').
controller('gameController', function() {
});
score-info.component.js:
angular.module('scoreInfo', [
'dataAccess'
]);
angular.
module('scoreInfo').
component('scoreInfo', {
templateUrl : '/score-info/score-info.template.html',
controller : function ScoreInfoController(dataAccess) {
self = this;
self.$onInit = function() {
dataAccess.game(self.gameId).then(function(game) {
self.game = game;
});
}
},
bindings : {
gameId : '<'
}
});
score-info.template.html:
<div>
Data available: {{ $ctrl.game != undefined }}
</div>
data-access.component.js:
angular.module('dataAccess', []);
angular.
module('dataAccess').
service('dataAccess',
function DataAccessService($http, $q) {
self = this;
self.game = function(game_id) {
var url = '/api/game/' + game_id;
return $http.get(url, { cache: true}).then(function(response) {
return response.data;
});
}
});
The behaviour is as follows:
The page renders with the content:
Data available: false
Data available: false
After some hundreds of milliseconds the $http -request finishes, the page is updated to the following state where only the latter component is updated.
Data available: false
Data available: true
It should be noted that the behaviour is the same even if the two components are of different types with different controllers, etc.

why factory don't work properly between the directives?

I make two directives .To communicate between two directives I used a factory .
but it not work properly ..I want to delete my text when I press delete button ..I take factory to do my task but it not working .I also try to take service .it also don't help
here is my code
http://plnkr.co/edit/Yenmira9J9XpjscQzRoX?p=preview
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="style.css">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
</head>
<body ng-app="app">
<a></a>
<b></b>
<script>
angular.module('app',[]).directive('a',function(){
return {
restrict :'E',
scope:{},
templateUrl:'a.html',
controller:'ts',
controllerAs:'vm'
}
}).controller('ts',function(sharedService){
var vm=this;
vm.delete=function(){
alert('--');
sharedService.deletepro();
}
}).directive('b',function(){
return {
restrict :'E',
scope:{},
templateUrl:'b.html',
controller:'bb',
controllerAs:'vm'
}
}).controller('bb',function(sharedService){
var pm=this;
pm.message= sharedService.sendData();
}).factory('sharedService', function() {
var data = {};
function deletepro(){
data = {};
}
function sendData(){
var obj = {name:"pQr"};
data = obj;
return data;
}
return {
sendData: sendData,
deletepro: deletepro
};
});
</script>
</body>
</html>
After your controller is first initialized, data and vm.message reference the same object, but when you run deletepro then data references a new object, but vm.message still references the old one.
If you want to pass data in this way, you must never replace data with a new object (otherwise, controllers will have to get the new object again).
Instead of data = {};, try data.name = '';
It looks like you're expecting that it will update because data is a shared reference. But you are resetting it to {}, which breaks the reference. You instead need to modify it:
function deletepro(){
for(var prop in data){
delete data[prop];
}
}
Also, keep in mind a and b are both real html tags, not sure if there are any issues ovewriting the standard ,

Linkedin Api dynamic parameter passing

I have a chrome extension and on its content script which runs at local host
"content_scripts": [{
"js": ["lib/jquery.js", "searching_helper.js"],
"matches": [ "http://localhost:8089/*"]
}]
In searching_helper.js I am getting the public profile url of linkedin members from another content script.
chrome.runtime.sendMessage({u:true},function(response) {
console.log(response.ans);
linkedinProfileUrl = response.ans.profileUrl;
console.log('linkedinProfileUrl' + linkedinProfileUrl);
});
In linkedinProfileUrl variable I am getting the public profile url a linkedin profile being viewed.
Now what I want is that I have a server side code in which i have to give its url which is using linkedin api.
Server side code of
index.html file
<script type="text/javascript" src="https://platform.linkedin.com/in.js">
//here goes the api key, and the callback function
api_key: ******
onLoad: onLinkedInLoad
authorize: true
</script>
the function which runs on onload is defined in linkedin.js file
function onLinkedInLoad() {
onLinkedInLogin();
}
//execute on login event
function onLinkedInLogin() {
//pass user info to angular
angular.element(document.getElementById("appBody")).scope().$apply(
function($scope) {
$scope.getLinkedInData();
}
);
}
and this getLinkedInData() method is defined in a controller .
$scope.getLinkedInData = function() {
if(!$scope.hasOwnProperty("userprofile")){
IN.API.Profile("https://in.linkedin.com/in/latika").fields(
[ "id", "firstName", "lastName", "pictureUrl",
"publicProfileUrl","positions","location","email-address"]).
In this IN.API.Profile("https://in.linkedin.com/in/latika") here I want to pass the linkedinProfileUrl got from the content script . and the problem is that if I pass parameters in index.html file it throws error.
I got the answer . I used localStorage to get the url.
In searching_helper.js used
localStorage.setItem('url', linkedinProfileUrl);
And then in linkedin.js used
function onLinkedInLogin() {
var url = localStorage.getItem('url');
//pass user info to angular
angular.element(document.getElementById("appBody")).scope().$apply(
function($scope) {
$scope.getLinkedInData(url);
}
);
}

I am not able to get response from web service using Angular javascript

var msg = document.getElementById('inputXML').innerHTML;How to pass input xml as a parameter to web service and displaying response from web service using angular javascript in html.
Here is my code, please help, i m not able to get reponse from web service.
<div ng-app="customerApp" ng-controller="customersController">
<ul>
HI<br><br><li ng-repeat="x in names">{{x}}</li>
</ul>
</div>
<script>
var app = angular.module('customerApp');
app.factory(
"setAsXMLPost",
function() {
//prepare the request data for the form post.
function transformRequest(data, getHeaders) {
var headers = getHeaders();
headers[ "Content-type" ] = "text/xml; charset=utf-8";
// using parsexml for xml
return(jQuery.parseXML(data));
}
return(transformRequest);
}
);
function customersController($scope, $http, setAsXMLPost) {
var msg = document.getElementById('inputXML').innerHTML;
$http.post("url.asmx", msg, {transformRequest: setAsXMLPost}).success(function(response) {
$scope.names = response;
});
}
</script>
<div id="inputXML">
<ACORD> <SignonRq> <UserId>CUser</UserId> <Password>XuViDgegi/KtGyJuXfuMrw==</Password>
<SignonPswd> <CustId> < </ACORD>
</div>
Because you are not retriving the content of the div. You are simply extracting #inputXML node from the DOM tree. You can try is
var msg = document.getElementById('inputXML').innerHTML;
I am not sure about xml but you are not posting it, use innerHTML to get actual xml from <div id="inputXML">.
inputXML : msg.innerHTML // use innerHTML to get the actual xml
Have you checked if your controller is executing correctly, I think the standard controller declaration would be something like this:
.controller('customersController', ['$scope', '$http', 'setAsXMLPost',function($scope, $http, setAsXMLPost){
var msg = document.getElementById('inputXML').innerHTML;
$http.post("http://nordevd208wa1x.csc-fsg.com/TPOServiceEnh7/TPOService/TPOService.asmx", msg, {transformRequest: setAsXMLPost}).success(function(response) {
$scope.names = response;
});
}]);
in var msg you are getting a javascript object though you need complete html to process so it should be
var = document.getElementById('inputXML').innerHTML;
Also default tranformRequest of $http in angular js is json you will have to change it to text/xml i wrote an article on how you could change it tranformRequest example angularjs
complete example, filename is test.php placed at root
<?php
if ( $_SERVER['REQUEST_METHOD'] === 'POST' ){
$xmlData = file_get_contents('php://input');
header("Content-type: text/xml; charset=utf-8");
echo '<?xml version="1.0" encoding="utf-8"?>' . $xmlData;
exit;
}
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<body >
<title>Simple xml post in angularjs Web Application</title>
<meta name="Description" content="Simple xml post in angularjs Web Application">
<div ng-app="customerApp" ng-controller="customersController">
<ul>
<li ng-repeat="x in users">{{x}}</li>
</ul>
</div>
<div id="inputXML">
<ACORD>
<SignonRq><UserId>CUser1</UserId><Password>XuViDgegi/KtGyJuXfuMrw==</Password></SignonRq>
<SignonRq><UserId>CUser2</UserId><Password>XuViDgegi/KtGyJuXfuMrw==1</Password></SignonRq>
</ACORD>
</div> <!-- Libraries -->
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.3/angular-route.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script>
var app = angular.module('customerApp', []);
app.factory(
"setAsXMLPost",
function() {
//prepare the request data for the form post.
function transformRequest(data, getHeaders) {
var headers = getHeaders();
headers[ "Content-type" ] = "text/xml; charset=utf-8";
// using parsexml for xml
return(jQuery.parseXML(data));
}
return(transformRequest);
}
);
app.factory(
"getAsXML",
function() {
//prepare the request data for the form post.
function transformResponse(data, getHeaders) {
var headers = getHeaders();
headers[ "Content-type" ] = "text/xml; charset=utf-8";
// using parsexml for xml
return(jQuery.parseXML(data));
}
return(transformResponse);
}
);
function customersController($scope, $http, setAsXMLPost, getAsXML) {
var msg = document.getElementById('inputXML').innerHTML;
$scope.users = [];
$http.post("test.php", msg, {transformRequest: setAsXMLPost, transformResponse: getAsXML}).success(function(returnedXMLResponse) {
//here you will get xml object in reponse in returnedXMLResponse
});
}
</script>
</body>
</html>

Angular Load LinkedIn Scripts From Partial

I am using LinkedIn API and I need to load their login scripts when my user hits a certain route. However , from what I've read in stackoverflow it is not possible to just put the script elements inside a partial .
my code is straight forward :
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular-route.js">
...
<script src="http://platform.linkedin.com/in.js">
api_key: ...
authorize: true
onLoad: onLinkedInLoad
</script>
<script type="in/Login">
Hello, <?js= firstName ?> <?js= lastName ?>.
</script>
<script src="js/linkedinFuncs.js"></script>
</div>
The 3 last scripts (the linkedin ones) only needs to be included when the user hits the 'login' route . Any thoughts?
If anyone experiences this issue :
1)Make sure you load jquery BEFORE angular
2)Run the latest angular (this issue is resolved on 1.2.9 but was unresolved for me on 1.2.0)
You could load it from the code in your relevant congtroller programmatically by using something like this
(function injectScript() {
var src = 'http://platform.linkedin.com/in.js',
script = document.createElement('script');
script.async = true;
script.src = src;
var api_key = 'YOUR_KEY_HERE';
//script.authorize = true;
script.text = 'api_key: ' + api_key + '\n' + 'authorize: true\n';
script.onload = function() {
IN.Event.on(IN, 'systemReady', function() {
loadDeferred.resolve(IN);
});
};
document.getElementsByTagName('head')[0].appendChild(script);
})();

Resources