how to use callback function in angular 4? - angularjs

I have used to get current address using google api and now i want implement callback function in this function using angular 4 how can implement it?
let currgeocoder = new google.maps.Geocoder();
currgeocoder.geocode({
'location': location
}, function(results:any, status:any) {
if (status == google.maps.GeocoderStatus.OK) {
let place = results[0];
//this.showresult(place.formatted_address);
} else {
alert('Geocode was not successful for the following reason: ' + status);
}
});
this.myGroup.setValue({
searchControl: 'global'
});

you can create oberservable and push new values on it ,
let subject = new Subject();
let ovservable = subject.asObservable()
subject.next("b");
ovservable.subscribe((value) => {
console.log("Subscription got", value); // Subscription wont get
// anything at this point
});
so create observable , expose it and when you receive data from call make use of .next() method that will do
in your code
let subject = new Subject();
let ovservable = subject.asObservable();
let currgeocoder = new google.maps.Geocoder();
currgeocoder.geocode({
'location': location
}, function(results:any, status:any) {
if (status == google.maps.GeocoderStatus.OK) {
let place = results[0];
subject.next(place);
//this.showresult(place.formatted_address);
} else {
alert('Geocode was not successful for the following reason: ' + status);
}
});
this.myGroup.setValue({
searchControl: 'global'
});
ovservable.subscribe((value) => {
console.log("Subscription got", value); // Subscription wont get
// anything at this point
});

Related

Angular template won't load. Even with $loaded. Data resolves after Load

Using AngularFire, Angular, Firebase.
I load a list of users from a Firebase Database. I use $loaded to ensure it waits until data loads.
I take this list, compare it against another firebase database of groups and push the results into two arrays.
Based on the console.logs the data sorts correctly. However, inside my template I get a blank page (I think this is because the page loads before the data is sorted).
Thoughts?
let userLoggedIn = AuthFactory.getUser();
var allUsersArray = $firebaseArray(ConnectFactory.fbUserDb);
var x = firebase.database().ref('groups');
var friendArr = [];
var notFriendArr = [];
allUsersArray.$loaded().then(function(){
angular.forEach(allUsersArray, function(user, i) {
var haveIAdded = x.child(userLoggedIn).child(allUsersArray[i].uid).once('value').then(function (snap) {
if (snap.val() !== null) {
return true;
} else {
return false;
}
});
var haveTheyAdded = x.child(allUsersArray[i].uid).child(userLoggedIn).once('value').then(function (snap) {
if (snap.val() !== null) {
return true;
} else {
return false;
}
});
Promise.all([haveIAdded, haveTheyAdded]).then(function([you, they]) {
if (you && they) {
console.log('We Are Friends', allUsersArray[i]);
friendArr.push(allUsersArray[i]);
} else {
console.log('not a friend ', allUsersArray[i]);
notFriendArr.push(allUsersArray[i]);
}
});
});
$scope.friendList = friendArr;
$scope.notFriendList = notFriendArr;
});
Alright, this time I tried to actually read the question before attempting to answer. ;-)
When you set your $scope.friendList and $scope.notFriendList within the $loaded promise, your Promise.all may (and most likely) havn't resolved yet when those are called, since angular.forEach doesn't wait for the promises to finish before moving on to the next statement in the function. So you'll have to build an array of promises and wait for them all to resolve outside of the loop before attempting to set your $scope variables.
allUsersArray.$loaded().then(function(){
var promises = [];
var friendArr = [];
var notFriendArr = [];
angular.forEach(allUsersArray, function(user, i) {
... // Same as before
promises.push(
Promise.all([haveIAdded, haveTheyAdded]).then(function([you, they]) {
if (you && they) {
console.log('We Are Friends', allUsersArray[i]);
friendArr.push(allUsersArray[i]);
} else {
console.log('not a friend ', allUsersArray[i]);
notFriendArr.push(allUsersArray[i]);
}
})
);
});
Promise.all(promises).then(function(){
$scope.friendList = friendArr;
$scope.notFriendList = notFriendArr;
});
});

Qooxdoo Remote table getRowCount() return 0

qx.Class.define("webApp.backendjs.tables.RegionesModel", {
extend: qx.ui.table.model.Remote,
members: {
_loadRowCount: function () {
var params = {};
params.action = "getCount";
var rpc = new qx.io.remote.Rpc("http://qx.alpali.cl/svc/svc.php");
rpc.setProtocol("2.0");
rpc.setCrossDomain(true);
rpc.callAsync(qx.lang.Function.bind(this._onRowCountCompleted, this), "regiones.regiones.getNominaRegiones", params);
},
_onRowCountCompleted: function (result, exc) {
if (result !== null) {
this._onRowCountLoaded(result.count);
}
},
_loadRowData: function (firstRow, lastRow) {
var params = {};
params.action = "getData";
var rpc = new qx.io.remote.Rpc("http://qx.alpali.cl/svc/svc.php");
rpc.setProtocol("2.0");
rpc.setCrossDomain(true);
rpc.callAsync(qx.lang.Function.bind(this._onLoadRowDataCompleted, this), "regiones.regiones.getNominaRegiones", params);
},
_onLoadRowDataCompleted: function (result, exc) {
if (result !== null) {
this._onRowDataLoaded(result);
}
}
}
});
var RTRegionesModel = new webApp.backendjs.tables.RegionesModel();
RTRegionesModel.setColumns(["ID", "Cè´¸digo", "Nombre"], ["id", "region_id", "region_nombre"]);
var TableRegiones = new qx.ui.table.Table(RTRegionesModel);
TableRegiones.setTableModel(RTRegionesModel);
// THIS don't work, return 0
TableRegiones.addListener('appear', function () {
console.log("RTRegionesModel.getRowCount(): %s", RTRegionesModel.getRowCount());
}, RTRegionesModel);
// THIS don't work, return 0
TableRegiones.addListener('appear', function () {
console.log("RTRegionesModel.getRowCount(): %s", RTRegionesModel.getRowCount());
}, this);
this.getRoot().add(TableRegiones);
var button1 = new qx.ui.form.Button("How many record...", "icon/22/apps/internet-web-browser.png");
this.getRoot().add(button1,{right:50,top:50});
// this is ok, return teh value
button1.addListener("execute", function(e) {
console.log("RTRegionesModel.getRowCount(): %s", RTRegionesModel.getRowCount());
});
url for testing playground
i need the valor when remote table is loaded
what is the problem..???
thank.
PD: sorry for my bad and ugly english, my native language is spanish (chile), my best friend in this moment is googol
At the time that you are looking for the row count with your "THIS don't work" comment, the row count is not yet available because the network operation to retrieve the row count from the server has not yet been issued.
You probably want to be listening for the model's dataChanged event which is fired when a row count is loaded, or when the model data changes, such as this:
TableRegiones.getTableModel().addListener(
'dataChanged',
function ()
{
console.log(
"dataChanged: RTRegionesModel.getRowCount(): %s",
RTRegionesModel.getRowCount());
},
RTRegionesModel);

Lighthouse/Service Worker, how to return http 200 when offline

My application currently uses webpack,angular js, and a service worker.
Using sw-precache plugin to create my service worker.
https://www.npmjs.com/package/sw-precache-webpack-plugin
The service worker caching is going well and I can see my static resources being fetched from serviceworker.js from chrome dev tools.
Now when I run the lighthouse report I am getting the following error still :
URL responds with a 200 when offline
https://github.com/GoogleChrome/lighthouse
In Dev tools when I switch on offline, I can actually see my page load. Some errors in console for some 3rd party scripts failing. Is this the reason for not getting url response 200 because I have some console errors from 3rd party i.e. sample error :
GET https://fonts.googleapis.com/css?family=Roboto+Slab:300,400,700 net::ERR_INTERNET_DISCONNECTED
What exactly is this audit looking for, and how can I achieve it ?
Edit : I added a picture of my network tab when I turn on offline, as I said the page loads fine. I notice my sw.js get's loaded from disk cache which I don't notice on other sites so could be something there.
Also here is sw.js content
'use strict';
var precacheConfig = [["/css/app.styles.77e2a0c3e7ac001193566741984a07f0.css","77e2a0c3e7ac001193566741984a07f0"],["/css/vendor.styles.582e79ead0684a8fb648ce9e543ad810.css","582e79ead0684a8fb648ce9e543ad810"],["/favicon.ico","70ef569d9a12f6873e86ed57d575cf13"],["/fonts/MaterialIcons-Regular.eot","e79bfd88537def476913f3ed52f4f4b3"],["/fonts/MaterialIcons-Regular.svg","a1adea65594c502f9d9428f13ae210e1"],["/fonts/MaterialIcons-Regular.ttf","a37b0c01c0baf1888ca812cc0508f6e2"],["/fonts/MaterialIcons-Regular.woff","012cf6a10129e2275d79d6adac7f3b02"],["/fonts/MaterialIcons-Regular.woff2","570eb83859dc23dd0eec423a49e147fe"],["/icons/launcher-icon-2x.png","91896b953c39df7c40b4772100971220"],["/icons/launcher-icon-3x.png","0aee2add7f56559aeae9555e495c3881"],["/icons/launcher-icon-4x.png","b164109dd7640b14aaf076d55a0a637b"],["/images/aa_logo_only.png","b5b46a8c2ead9846df1f1d3035634310"],["/images/developer.png","e8df747b292fe6f5eb2403c7180c31da"],["/images/facebook.png","8ab42157d0974099a72e151c23073022"],["/images/home-bg.jpeg","0a0f7da8574b037463af2f1205801e56"],["/images/logo.png","e8712312e08ca427d79a9bf34aedd6fc"],["/images/map.png","af3443ef4ab2890cae371c7a3de437ed"],["/images/pattern.png","114d593511446b9a4c6e340f7fef5c84"],["/images/twitter.png","99da44949cd33e16d2d551d42559eaf2"],["/index.html","1e9b5c4b3abba7e13d8d28c98cfb3bb5"],["/js/app.d9ada27616bf469d794d.js","8e2fc74de7d5c122ab8f0aca7e31b075"],["/js/vendor.d9ada27616bf469d794d.js","3bbba4569b6f3b88881b0533260905fe"],["/manifest.json","4bea29155995b63a9f2855637c0fe74c"]];
var cacheName = 'sw-precache-v2-45-' + (self.registration ? self.registration.scope : '');
var ignoreUrlParametersMatching = [/^utm_/];
var addDirectoryIndex = function (originalUrl, index) {
var url = new URL(originalUrl);
if (url.pathname.slice(-1) === '/') {
url.pathname += index;
}
return url.toString();
};
var createCacheKey = function (originalUrl, paramName, paramValue,
dontCacheBustUrlsMatching) {
// Create a new URL object to avoid modifying originalUrl.
var url = new URL(originalUrl);
// If dontCacheBustUrlsMatching is not set, or if we don't have a match,
// then add in the extra cache-busting URL parameter.
if (!dontCacheBustUrlsMatching ||
!(url.toString().match(dontCacheBustUrlsMatching))) {
url.search += (url.search ? '&' : '') +
encodeURIComponent(paramName) + '=' + encodeURIComponent(paramValue);
}
return url.toString();
};
var isPathWhitelisted = function (whitelist, absoluteUrlString) {
// If the whitelist is empty, then consider all URLs to be whitelisted.
if (whitelist.length === 0) {
return true;
}
// Otherwise compare each path regex to the path of the URL passed in.
var path = (new URL(absoluteUrlString)).pathname;
return whitelist.some(function(whitelistedPathRegex) {
return path.match(whitelistedPathRegex);
});
};
var stripIgnoredUrlParameters = function (originalUrl,
ignoreUrlParametersMatching) {
var url = new URL(originalUrl);
url.search = url.search.slice(1) // Exclude initial '?'
.split('&') // Split into an array of 'key=value' strings
.map(function(kv) {
return kv.split('='); // Split each 'key=value' string into a [key, value] array
})
.filter(function(kv) {
return ignoreUrlParametersMatching.every(function(ignoredRegex) {
return !ignoredRegex.test(kv[0]); // Return true iff the key doesn't match any of the regexes.
});
})
.map(function(kv) {
return kv.join('='); // Join each [key, value] array into a 'key=value' string
})
.join('&'); // Join the array of 'key=value' strings into a string with '&' in between each
return url.toString();
};
var hashParamName = '_sw-precache';
var urlsToCacheKeys = new Map(
precacheConfig.map(function(item) {
var relativeUrl = item[0];
var hash = item[1];
var absoluteUrl = new URL(relativeUrl, self.location);
var cacheKey = createCacheKey(absoluteUrl, hashParamName, hash, false);
return [absoluteUrl.toString(), cacheKey];
})
);
function setOfCachedUrls(cache) {
return cache.keys().then(function(requests) {
return requests.map(function(request) {
return request.url;
});
}).then(function(urls) {
return new Set(urls);
});
}
self.addEventListener('install', function(event) {
event.waitUntil(
caches.open(cacheName).then(function(cache) {
return setOfCachedUrls(cache).then(function(cachedUrls) {
return Promise.all(
Array.from(urlsToCacheKeys.values()).map(function(cacheKey) {
// If we don't have a key matching url in the cache already, add it.
if (!cachedUrls.has(cacheKey)) {
return cache.add(new Request(cacheKey, {credentials: 'same-origin'}));
}
})
);
});
}).then(function() {
// Force the SW to transition from installing -> active state
return self.skipWaiting();
})
);
});
self.addEventListener('activate', function(event) {
var setOfExpectedUrls = new Set(urlsToCacheKeys.values());
event.waitUntil(
caches.open(cacheName).then(function(cache) {
return cache.keys().then(function(existingRequests) {
return Promise.all(
existingRequests.map(function(existingRequest) {
if (!setOfExpectedUrls.has(existingRequest.url)) {
return cache.delete(existingRequest);
}
})
);
});
}).then(function() {
return self.clients.claim();
})
);
});
self.addEventListener('fetch', function(event) {
if (event.request.method === 'GET') {
// Should we call event.respondWith() inside this fetch event handler?
// This needs to be determined synchronously, which will give other fetch
// handlers a chance to handle the request if need be.
var shouldRespond;
// First, remove all the ignored parameter and see if we have that URL
// in our cache. If so, great! shouldRespond will be true.
var url = stripIgnoredUrlParameters(event.request.url, ignoreUrlParametersMatching);
shouldRespond = urlsToCacheKeys.has(url);
// If shouldRespond is false, check again, this time with 'index.html'
// (or whatever the directoryIndex option is set to) at the end.
var directoryIndex = 'index.html';
if (!shouldRespond && directoryIndex) {
url = addDirectoryIndex(url, directoryIndex);
shouldRespond = urlsToCacheKeys.has(url);
}
// If shouldRespond is still false, check to see if this is a navigation
// request, and if so, whether the URL matches navigateFallbackWhitelist.
var navigateFallback = '';
if (!shouldRespond &&
navigateFallback &&
(event.request.mode === 'navigate') &&
isPathWhitelisted([], event.request.url)) {
url = new URL(navigateFallback, self.location).toString();
shouldRespond = urlsToCacheKeys.has(url);
}
// If shouldRespond was set to true at any point, then call
// event.respondWith(), using the appropriate cache key.
if (shouldRespond) {
event.respondWith(
caches.open(cacheName).then(function(cache) {
return cache.match(urlsToCacheKeys.get(url)).then(function(response) {
if (response) {
return response;
}
throw Error('The cached response that was expected is missing.');
});
}).catch(function(e) {
// Fall back to just fetch()ing the request if some unexpected error
// prevented the cached response from being valid.
console.warn('Couldn\'t serve response for "%s" from cache: %O', event.request.url, e);
return fetch(event.request);
})
);
}
}
});
Some data like
https://fonts.googleapis.com/css?family=Roboto+Slab:300,400,700
does not support offline mode download these file manually and add them with local path again.

Firebase .once(): Use success and failure callbacks

I have the following function in my Angular-app
$scope.retrieveProjectData = function() {
$scope.projectNumberNoChange = false;
// Only retrieve Data if the ProjectNumber changed
if (currentlySelectedProjectNumber != $scope.feedback.projectNumber.content) {
currentlySelectedProjectNumber = $scope.feedback.projectNumber.content;
// Go to database-reference based on the projectNumber
var projectsRef = firebaseDatabaseRef.child("projects");
var currentChild = projectsRef.child(currentlySelectedProjectNumber);
// retrieve data once and fill $scope.feedback
currentChild.once("value",
// If the project is found
function (dataSnapshot) {
// Fill selectedProject and hand over to writeDataFromSelectedProject()
var selectedProject = dataSnapshot.val();
// Fill $scope.feedback
writeDataFromSelectedProject(selectedProject);
},
// If no data is found
function () {
console.log("No data found");
});
}
// If the projectNumber didn't change, the projectNumberNoChangeMessage will be shown
else {
$scope.projectNumberNoChange = true;
}
};
The user has the possibility to load some data regarding his project-number (for instance: Name, email, tel) to make it faster for the user to fill a form.
In the part:
currentChild.once("value",
// If the project is found
function (dataSnapshot) {
// Fill selectedProject and hand over to writeDataFromSelectedProject()
var selectedProject = dataSnapshot.val();
// Fill $scope.feedback
writeDataFromSelectedProject(selectedProject);
},
// If no data is found
function () {
console.log("No data found");
});
only the first Callback-function is called, even if the projectNumber was not found. How can I use the "failureCallbackOrContext" as described in the docs?
Thanks for taking the time!
The problem was solved. I just checked the dataSnapshot.val() for beeing an object or null!

Transfer Items to and from users Using AngularJS and Firebase

Ok, so I'm working with AngularJS and Firebase and trying to create a simple exchange between two users. Right now my data structure is set up under "users/uId/" and then their email, date they joined, and gold.
Under gold (users/uId/gold) I have "sent" which captures the amount, time and to whom (email). This is the code snippet below. It also updates their total gold.
Now I'm stuck updating the person they're sending the gold to. I capture the email address, but everything under scope relates to the current logged in user. How would I update the new users users/uId/gold/received with the amount, time and email who it was from, along with updating their total gold?
I feel like I might be going about this the wrong way, any help would be appreciated, thanks!
ledger.controller('TransferController', function (
$scope, $firebase, $routeParams, $location, $rootScope, FIREBASE_URL) {
$scope.whichuser = $routeParams.uId;
$scope.goldsends = goldsendList;
var ref = new Firebase(FIREBASE_URL + '/users/' + $scope.whichuser + '/gold/' + '/sent/');
var hopperRef = new Firebase(FIREBASE_URL + '/users/' + $scope.whichuser + '/gold/');
var usersRef = ref.child("users");
var goldsendList = $firebase(ref).$asArray();
$scope.sendGold = function () {
var sendgoldObj = $firebase(ref); //this var has to match the sendgoldObj.$push var down below, and that's it
var myData = {
amount: $scope.user.amount,
email: $scope.user.email,
date: Firebase.ServerValue.TIMESTAMP
};
sendgoldObj.$push(myData).then(function () {
// $location.path('/myledger/'); //page redirect
}); //data sent to firebase.
if ($scope.currentUser.gold.total - Math.abs($scope.user.amount) > 0) { //
var hopperRefff = hopperRef.child("gold");
hopperRef.update({
"total": $scope.currentUser.gold.total - $scope.user.amount
}); //update total gold
var receive = new Firebase(FIREBASE_URL);
ref.child('users').orderByChild('email').equalTo(emailAddress).once('value', function (snap) {
console.log(snap.name() + (snap.val() === null ? ' DOES NOT' : ' does') + ' exist');
}); //trying to find user to send gold to
} //if user has enough gold statement
else {
return {
scope: {
errormessage: 'You don\'t have enough money',
}
};
console.log("not enough money!");
} //else note enough gold statement
} //sendgold
}); //TransferController
You could store the users by email where the # is replaced by _ and a . is replaced with -
So you have a JSON structure like this in Firebase
users: {
"bob_hoskins-com": {
email: "bob#hoskins.com",
date: "09-09-1999",
gold: {
...
}
}
}
However, I don't think this is a great approach for this problem.
I would create a node service that is observing a requests Firebase location on each user for added children. The node service will then do the calculations and write the data to the correct paths, then can delete the request once processed.
So you would have rules on your Firebase like this
{
"rules": {
"$userId": {
"requests": {
".read": "auth != null && $userId == auth.id",
".write": "auth != null && $userId == auth.id"
},
"responses": {
".read": "auth != null && $userId == auth.id",
".write": "auth != null && $userId == auth.id"
}
}
}
Here is some request code
var Firebase = require('firebase');
function s4() {
return Math.floor((1 + Math.random()) * 0x10000)
.toString(16)
.substring(1);
}
function guid() {
return s4() + s4() + s4() + s4();
}
var _ref = new Firebase('https://YOUR_FIREBASE.firebaseio.com/');
//Log me in
var guid = guid();
var FirebaseTokenGenerator = require("firebase-token-generator");
var tokenGenerator = new FirebaseTokenGenerator("YOUR_TOKEN");
var TOKEN = tokenGenerator.createToken({uid: guid, user: "node server"},{admin: true});
_ref.authWithCustomToken(TOKEN, function (error) {
if(error) {
console.log("Login Failed!", error);
} else {
console.log("Login Succeeded!", guid);
}
});
_ref.on('child_added', function (user) {
var requests = user.ref().child('requests');
requests.on('child_added', function(req) {
handleRequest(req);
});
});
var handleRequest = function (request) {
// Process the request
// Write stuff back to Firebase
// Delete the request
request.ref().remove();
};
Setting a value to the user is just a variation of checking if that user exists. Once you have a snapshot, you can get back to a ref by calling ref
ref.child('users').orderByChild('email').equalTo(emailAddress).once('value', function (snap) {
snap.ref().update({ "total": snap.val().total + amount });
});
Not that this is just a sample, so you'll probably have to update it for your actual data structure.
Update
The above will get you the value of the users node.
You either need to capture the once('child_added' or forEach over the on('value'. I'll give an example of both.
Listening to child_added:
ref.child('users').orderByChild('email').equalTo(emailAddress).once('child_added', function (snap) {
snap.ref().update({ "total": snap.val().total + amount });
});
An example of looping over the value:
ref.child('users').orderByChild('email').equalTo(emailAddress).once('value', function (snap) {
snap.forEach(function(childsnap) {
childsnap.ref().update({ "total": snap.val().total + amount });
});
Here's a jsbin with both samples: http://jsbin.com/fenavu/1/edit?js,console. Note that the code here writes out the ref.toString(), which gives you the full URL of the node (since every piece of data in Firebase has its own unique URL). That can be a handy way to figure out what URL your node maps to.

Resources