How to bind remote JSON data to a Polymer vaadin-grid? - polymer-1.0

First time using this web component... I'm able to bind JSON data in a var to a vaadin-grid (w/ polymer 1.0), but am missing something basic about getting the JSON data from a url into the grid.
Here's the most simple example I could create, that worked with hard-coded JSON and now have used some of the examples from the Vaadin website to attempt to pull the data from a URL.
<head>
// import statements same as in my example that works with hard coded JSON
<script>
function getJSON(url, callback) {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) {
callback(JSON.parse(xhr.responseText));
}
};
xhr.open('GET', url, true);
xhr.send();
}
</script>
</head>
<body>
<h2>Vaadin Grid - example </h2><br>
<vaadin-grid selection-mode="multi">
<table>
<col name="name">
<col name="city">
</table>
</vaadin-grid>
<script>
var grid = grid || document.querySelector('vaadin-grid');
HTMLImports.whenReady(function() {
grid.items = function(params, callback) {
var url = 'https://.../simple-data.json';
getJSON(url, function(data) {
callback(data[0]);
});
};
});
</script>
And simple-data.json URL returns this:
[ { "name": "Jose Romero", "city": "Monteray" }, { "name": "Chuy Diez", "city": "Los Angeles" }, { "name": "Inez Vega", "city": "San Diego" } ]
Where am I going wrong? Thanks in advance.

Binding is easily done using the Polymer 1.0 iron-ajax component. Here's the working code:
<head>
// import statements same as in my example that works with hard coded JSON
<link rel="import" href="iron-ajax/iron-ajax.html">
<link rel="import" href="vaadin-grid/vaadin-grid.html">
</head>
<body>
<h2>Vaadin Grid - working example </h2><br>
<template is="dom-bind">
<iron-ajax
auto
url = "http://hostname/.../simple-data.json"
handle-as="json"
last-response="{{gridData}}" ></iron-ajax>
<vaadin-grid selection-mode="multi" items="{{gridData}}">
<table>
<col name="name">
<col name="city">
</table>
</vaadin-grid>
</template>
<script>
</script>
</body>
I still would like to learn how it's done using the JavaScript code in the Vaadin documentation Remote Data Any tips?

Answering my own question again: to bind JSON to a vaadin-grid using JavaScript instead of using the Polymer iron-ajax component simply add this script section to the bottom of the body. It adds an event listener for WebComponentsReady.
<script type="text/javascript">
window.addEventListener('WebComponentsReady', function() {
var grid = document.querySelector('vaadin-grid');
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
var json = JSON.parse(xhr.responseText);
grid.items = json;
}
}
};
xhr.open('GET', 'http://<your_url>', true);
xhr.send();
});
</script>
For others getting started with vaadin Polymer components they have a series of very short, but excellent tutorials - search YouTube for "vaadin elementary school" to find them.

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.

Badge on app icon for Android doesn't show even after implementing ngCordova (cordova-plugin-badge) and phonegap-plugin-push

I will really appreciate if anyone can help me with this issue that has been bugging me for days.
I have a hybrid app created using the Ionic framework, which I have implemented push notifications on (via phonegap-plugin-push). The push notifications work fine, but what I want is for the push notification (i.e. GCM payload) to send a badge count/number over to the application, and the application will take that count/number and displays it as a badge beside the app icon. My code works perfectly for iOS devices given that badges are already inbuilt, but I have difficulties with implementing the same idea (badges) on the Android platform.
I am aware that due to badges not being inbuilt into the Android platform, some devices might not be supported, but at least I want it to work for some devices (i.e. Samsung, Sony). I have done a lot of research, most prominently:
cordova-plugin-badge (https://github.com/katzer/cordova-plugin-badge) which stated in the documentation is supposed to work for both iOS and certain Android devices, but it doesn't work on any Android devices at all for me. Note that the Android devices I have been testing on are emulators from Genymotion, which I have set up Google Play Services on and are able to receive push notifications and function almost like a real device, will that be an issue?
ShortcutBadger (https://github.com/leolin310148/ShortcutBadger) which only has documentation for native Android implementation and supposedly utilised by cordova-plugin-badge as stated above to extend the support to hybrid Android apps, but this has been unable to help me at all.
My index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
<title></title>
<link href="css/style.css" rel="stylesheet">
<script src="lib/ionic/js/ionic.bundle.js"></script>
<script src="lib/ionic-platform-web-client/dist/ionic.io.bundle.min.js"></script>
<script src="js/ng-cordova.js"></script>
<script src="cordova.js"></script>
<script src="js/app.js"></script>
</head>
<body ng-app="starter">
<ion-pane>
<ion-header-bar class="bar-stable">
<h1 class="title">Trade Deals</h1>
</ion-header-bar>
<ion-content ng-controller="badgeController">
<div>Number of deals pending now: </div>
<div class="deals"></div>
<button class="button" ng-click="setBadge(10)">Set badge 10</button>
<button class="button" ng-click="hasPermission()">Show permission</button>
<button class="button" ng-click="get()">Get badge count</button>
<button class="button" ng-click="clear()">Clear badge count</button>
<button class="button" ng-click="increase()">Increase by 1</button>
<button class="button" ng-click="decrease()">Decrease by 1</button>
</ion-content>
</ion-pane>
</body>
</html>
My app.js:
angular.module('starter', ['ionic', 'ngCordova'])
/*
* do a ionic.push register() every time the app launches for the first time
* so that it is guaranteed that there is always a valid device token for GCM/APNS
*/
.run(function($ionicPlatform, $cordovaBadge) {
$ionicPlatform.ready(function() {
console.log("Device platform is "+device.platform);
var push = new Ionic.Push({
"debug": true,
"onNotification": function(notification) {
console.log("notification received!!!");
var payload = notification.payload;
var payloadStr = JSON.stringify(payload, null, 4);
var notiStr = JSON.stringify(notification, null, 4);
console.log("notification: "+notiStr);
var countIndex = notiStr.indexOf("count"); // extracting badge count from the GCM payload
var badgeIndex = countIndex + 9;
var badgeNo;
if (!isNaN(notiStr[badgeIndex+1])) {
badgeNo = notiStr.substr(badgeIndex,badgeIndex+2);
}
else {
badgeNo = notiStr[badgeIndex];
}
if (device.platform == "Android") {
$cordovaBadge.set(badgeNo);
}
},
"onRegister": function(data) {
console.log(data.token);
},
"pluginConfig": {
"android": {
"sound": "true",
"badge": "true",
"icon": "icon",
"iconColor": "lime"
},
"ios": {
"alert": "true",
"badge": "true",
"sound": "true"
},
}
});
push.register(function(token) {
console.log("My Device token:",token.token);
//window.alert("The token is "+token.token);
push.saveToken(token); // persist the token in the Ionic Platform so that it doesn't change on multiple launches
});
$cordovaBadge.get().then(function(badge) {
document.querySelector(".deals").innerHTML = badge;
});
});
})
.controller("badgeController", function($scope, $ionicPlatform, $cordovaBadge) {
console.log("inside badgeController");
$ionicPlatform.ready(function() {
$ionicPlatform.on('resume', function() {
$cordovaBadge.get().then(function(badge) {
document.querySelector(".deals").innerHTML = badge;
});
});
//$cordovaBadge.configure({autoClear: true}); // configure to clear all notifications whenever user opens the app
$scope.setBadge = function(value) {
console.log("inside setBadge");
$cordovaBadge.hasPermission().then(function(result) {
$cordovaBadge.set(value);
window.alert("Badge count is "+value);
}, function(error) {
console.log(JSON.stringify(error)); // display error message
});
}
$scope.hasPermission = function() {
console.log("inside hasPermission");
$cordovaBadge.hasPermission().then(function(result) {
window.alert("User has permission: "+result);
console.log("device has permission");
}, function(error) {
console.log(JSON.stringify(error)); // display error message
});
}
$scope.get = function() {
console.log("inside get");
$cordovaBadge.hasPermission().then(function(result) {
$cordovaBadge.get().then(function(badge) {
if (badge>=0) {
document.querySelector(".deals").innerHTML = badge;
}
})
}, function(error) {
console.log(JSON.stringify(error)); // display error message
});
}
$scope.clear = function() {
console.log("inside clear");
$cordovaBadge.hasPermission().then(function(result) {
$cordovaBadge.clear();
window.alert("Cleared badge count");
}, function(error) {
console.log(JSON.stringify(error)); // display error message
});
}
$scope.increase = function() {
console.log("inside increase");
$cordovaBadge.hasPermission().then(function(result) {
$cordovaBadge.increase();
window.alert("Increased badge count");
}, function(error) {
console.log(JSON.stringify(error)); // display error message
});
}
$scope.decrease = function() {
console.log("inside decrease");
$cordovaBadge.hasPermission().then(function(result) {
$cordovaBadge.decrease();
window.alert("Good job!");
//window.alert("Decreased badge count");
}, function(error) {
console.log(JSON.stringify(error)); // display error message
});
}
});
});
Also, is the issue that the app icon has to be converted to a widget in order for the badges to work? I am not sure how the cordova-plugin-badge is implemented and the instructions didn't say anything about widgets being needed for Android.
Thank you and any help/tips is appreciated :) I have been troubleshooting this for days and it's rather frustrating.
Stock Android does not offer this functionality at the moment on the standard launcher.
Certain manufacturers (e.g. Samsung notably) have included this functionality into their customised Android launchers. Also some 3rd-party launchers (e.g. Nova Launcher) have included an API to accomplish this.
You may want to check following links for further explaination:
How does Facebook add badge numbers on app icon in Android?
Does Samsung modifies it's Android ROMs to have badges on email and SMS icons?
How to make application badge on android?
Regards

multi data from different schema, angular display

I have a really long json that each comes from different schema.
I did push in order to get them all in one json - that works.
know I want to use a controller for all of them and display it to the screen.
my index
<!DOCTYPE html>
<html ng-app="showFrozen">
<head>
<title>frozen</title>
<link rel="stylesheet" type="text/css" href="css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="css/bootstrap-theme.min.css">
</head>
<body ng-controller="showFrozenCtrl">
<tbody>
<div ng-repeat="themes in showFrozenController.themes" ng-show="$first">
<h2>{{themes.theme}}</h2>
<span>for age: </span>
<p>{{themes.age}}</p>
<span>description: </span>
<p>{{themes.description}}</p>
<p>{{themes.description_more}}</p>
<img ng-src="{{themes.image}}" width="170" height="170">
</div>
</table>
<script src="js/lib/angular/angular.min.js"></script>
<script src="js/showFrozenController.js"></script>
</body>
</html>
my controller
var showFrozen = angular.module('showFrozen',[]);
showFrozen.filter("allItems", function() {
return function(frozen) {
var resultArr = [];
angular.forEach(frozen,function(item) {
resultArr.push(item);
});
return resultArr;
};
});
var model = {};
showFrozen.run(function($http) {
$http.get("http://localhost:3000/frozen").success(function(data){
console.log(data);
model.frozen = data;
});
});
showFrozen.controller('showFrozenCtrl',function($scope) {
$scope.showFrozenController = model;
});
so I don't get any output - but I see the json in the console, I'm attaching an image.
In your controller model is undefined.
Move the HTTP call to your controller and in the success assign the scope.showFrozenController to data
You need to make your $http request inside of your controller.
showFrozen.controller('showFrozenCtrl',function($scope, $http) {
$http.get("http://localhost:3000/frozen").success(function(data){
console.log(data);
$scope.model = data;
});
});
This is because when you try and print items out in your template (html) what is actually being accessed inside of any {{ }} blocks is your $scope object. So to make data available to your template you must store it on your $scope.
Have a read of this blog post
showFrozen.factory('frozenDataSrv',function($http) {
return {
getFrozenData: getFrozenData
};
function getFrozenData() {
return $http.get("http://localhost:3000/frozen")
.then(getFrozenDataComplete)
.catch(getFrozenDataFailed);
function getFrozenDataComplete(response) {
return response.data.results;
}
function getFrozenDataFailed(error) {
logger.error('XHR Failed for getFrozenData.' + error.data);
}
}
});
showFrozen.controller('showFrozenCtrl',function($scope, frozenDataSrv) {
frozenDataSrv.getFrozenData()
.then(function(response){
console.log(response)
})
});

ng-repeat not printing resp.items from cloudendpoint on webpage

I'm new to angularjs. I'm working on a web application using angularjs and cloud endpoints. I'm getting the response from endpoint and I can see that in Console.log also. but when I'm trying to print that response it's not working. I'm not getting what's going wrong. Can anyone fix this?
Here's my code.
HTML Page
<div ng-repeat="lister in lists">
</div><h2>{{lister.title}}</h2>
</div>
AngularJs Code
<script>
function init() {
window.init();
}
</script>
<script>
var app = angular.module('list',[]);
app.controller('listCtrl',function($scope,$window){
$window.init= function() {
$scope.loader();
};
$scope.loader= function(){
gapi.client.load('MyEndPoint', 'v1', function(){
gapi.client.MyEndPoint.MyMethod1({
'latitude':'24.5555','longitude':'45.55555'
}).execute(function(resp) {
$window.console.log(resp);
$scope.lists = resp.items;
});
}, 'https://MyEndpointURL.appspot.com/_ah/api');
};
</script>

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>

Resources