angularjs: open a page then only loading data - javascript

My current ionic code able to get data then open the page. However, I want to open the page then only loading to get the data. I want to change the sequence since it takes 10s to load some data.
Here is my code:
$scope.openDetail = function (stock) {
console.log(stock.symbol);
$ionicLoading.show();
//stockCondition
if(stock.symbol.length<=$scope.stockCondition) {
$stockDataFactory.getStockDetails(stock).then(
function success(data) {
$globalFactory.personalStockData = data.details;
$globalFactory.personalStockNews = data.news;
$ionicLoading.hide();
$state.go("app.page1");
},
function error(error) {
alert(error.message);
console.error(error);
$ionicLoading.hide();
}
);
}
else{//WarrentCondition
$stockDataFactory.getWarrentDetails(stock).then(
function success(data) {
$globalFactory.personalStockData = data.details;
$globalFactory.personalStockNews = {};
$ionicLoading.hide();
$state.go("app.page1");
},
function error(error) {
alert("Stocks Not Found.");
console.error(error);
$ionicLoading.hide();
}
);
}
};//end
In order to open the $state.go("app.page1"); first, then only loading data, how shall I made changes of my code?

You should show the page1's html templet .
My approach will be using ng-if="personalStockData" with the $setTimeout() trick to show the data only when it's loaded. looks something like this
//page1 controller
$stockDataFactory.getStockDetails(stock).then(
function success(data) {
$setTimeout(function(){
$scope.personalStockData = data.details;
$scope.personalStockNews = data.news;
})
},
function error(error) {
alert(error.message);
console.error(error);
$ionicLoading.hide();
}
);
html
<div>
...
<div ng-if="personalStockData">
</div>
<div ng-if="personalStockNews">
</div>
...
</div>
anyways try not to use global variables, those are really hard to track.

You'll have to bring over the decision data that are explicit to the current page over to app.page1. For instance $scope.stockCondition. I suspect it is the same forstock.symbol. Will have to see what stock variable is.
There are many ways you can achieve this. Using query string is one option and is also the most conventional way. Some people prefer to store them in cookies, not efficient but applies to certain use-cases.
Again, I am not sure what $state is. Assuming it is angular-ui-router's statemanager. Then you can achieve this by;
$state.go("app.page1", {
stockCondition: $scope.stockCondition,
stocksymLen: stock.symbol.length
});
Then on app.page controller you can retrieve the values of the query string parameters by doing $state.params.stockCondition.
Once you have brought the decision variables across to the next page. The next step would be to plug them into the if-else statement you got from the other page onto app.page1.
Pseudo code:
angular.module('blah')
.controller('app.page1', function($scope, $state) {
// on page load
if($state.params.stocksymLen <= $state.params.stockCondition) {
// do your REST call
...
else {
...
}
});

Related

How do i get the relative path with JQuery?

I recognize that this has been asked before but I have yet to find an answer that is working for me. I'm basically following a solution for keeping an ASP session alive I found at dotnetcurry by Malcom Sheridan.
I have the following JQuery defined on the masterpage of an asp.net site. As the default page is on the same level, it has no problems making the serverside call every 7 seconds; however, when I navigate to another page, deeper in the file structure, the ajax post starts to fail.
var interval;
$(function () {
setheartbeat();
});
function setheartbeat() {
interval = setInterval("heartbeat()", 7000);
}
function heartbeat() {
$.post("./SessionHeartbeat.ashx", null, function (data) {
})
.done(function () {
alert('done');
})
.fail(function () {
clearInterval(interval);
alert('Failed to keep session alive. Please close the browser and log back in.');
});
}
Besides the sample from above, I've already tried, with none of them working:
$.post("/SessionHeartbeat.ashx", null, function(data) {...}
$.post(window.location.pathname + "/SessionHeartbeat.ashx", null, function(data) {...}
$.post(vpath + "/SessionHeartbeat.ashx", null, function(data) {...} where vpath = "<%=ApplicationVirtualPath %>"; after I've included the System.Web.Hosting.HostingEnvironment namespace
Anyone have any thoughts?
Thank you

LinkedIn Javascript SDK Fail To Return Positions

I am trying to use LinkedIn Javascript SDK to retrieve some information including positions fields. I copied the code from the internet but it seems something is not working quite right because the code i copied doesn't return positions fields as supposed to be. I tried on ApiGee it worked fine and it returned the list of positions as i am expected. If you look at the code below , do you think i missed something or the javascript SDK itself has some buggy problems ?
<script type="text/javascript" src="//platform.linkedin.com/in.js">
api_key: yourapikey
authorize: true
onLoad: onLoad
</script>
<script type="text/javascript">
function onLoad() {
IN.Event.on(IN, "auth", getProfileData);
}
// Handle the successful return from the API call
function onSuccess(data) {
alert(JSON.stringify(data));
}
// Handle an error response from the API call
function onError(error) {
console.log(error);
}
// Use the API call wrapper to share content on LinkedIn
function getProfileData() {
//alert(IN.ENV.auth.oauth_token);
IN.API.Raw("/people/~:(id,positions)?format=json").result(onSuccess).error(onError);
}
</script>
Return result is showing this :
{"id":"wQplQQjzLa","positions":{"_total":0}}
Hello there #John Hadikusumo,
Well, I do understand that this reply would be happening only a year later but, I too was facing some problems with the linkedin api integration especially when it came to the "positions" object values.
Apparently when I got an error, what it meant was that the user who is using his linkedin profile to authorize, that particular user has not initiated his experience details and thus has no value;
To circumvent this particular problem here is what I had done which had helped me:
function onLinkedInLoad() {
IN.Event.on(IN, "auth", getProfileData);
}
function onSuccess(data) {
console.log(data);
}
function onError(error) {
console.log(error);
}
function getProfileData(){
IN.API.Profile("me").fields(["firstName","lastName", "email-address", "positions"]).result(function(data) {
var profileData = data.values[0];
var profileFName = profileData.firstName;
var profileLName = profileData.lastName;
//this is the piece of code that helped me out;
//might work for you as well;
if(data.values[0].positions._total == "0" || data.values[0].positions._total == 0 || data.values[0].positions._total == undefined) {
console.log("Error on position details");
var profileCName = "Details Are Undefined";
}
else {
var profileCName = profileData.positions.values["0"].company.name;
}
var profileEName = profileData.emailAddress;
//and other logic/code continues...
});
}
So I do hope this helps you out. Do let me know if you had faced any other errors, I could use some help in case I would need to improve my existing code.
Cheers and Have a nice day.

Including a local version of a library that failed to load

I am using PhantomJS to take a screenshot of a page every five minutes, and it works correctly most of the time. The problem is that sometimes the page I am taking a screenshot of fails to load the AngularJS library, and then, it can't build the page after that. So I am trying to figure out how to load a local copy in its place. Here is what I have been trying...
var page = require('webpage').create(),system = require('system');
var home = 'https://smartway.tn.gov/traffic/';
page.open(home, function (status) {
if(status === "success"){
page.injectJs('angular.js');
window.setTimeout((function() {
page.evaluate(function () {
/*stuff*/
});
}), 2000);
}
});
So angular.js is the name of my local copy of what the site would normally download. The site calls the script at the end of the body with several other scripts, and I am trying to find the best way to include it. I am wondering if it needs to be included by replacing the script tag in the html so it can be loaded in sequence, but I am not sure how to do that.
Thanks
It is problematic to reload a single JavaScript file when it failed, particularly when it is the framework. There are probably many scripts which depend on it. When the core framework is not loaded, those scripts will stop executing, because the angular reference cannot be resolved.
You could inject a local version of angular, but then you would have to go over all the other scripts which reference angular and "reload" them by either downloading and evaling them in order or putting them into the page as script elements. I advise against it, because it is probably very error prone.
You should just reload the page if angular does not exist after page load (callback of page.open). Since the same problem may occurr during reload, this has to be done recursively:
function open(countDown, done){
if (countDown === 0) {
done("ERROR: not loaded");
return;
}
page.open(home, function (status) {
if(status === "success"){
var angularExists = page.evaluate(function () {
return !!angular;
});
if (angularExists){
done();
} else {
open(countDown - 1, done);
}
} else {
open(countDown - 1, done);
}
});
}
open(5, function(err){
if(err) {
console.log(err);
} else {
page.render(target);
}
});
You can also try the page.reload() function instead of a page.open().
The other possiblity is to always inject the local version when the page loading began and stop any request for the remote version of the script:
page.onLoadStarted = function() {
page.injectJs('angular.js');
};
page.onResourceRequested = function(requestData, networkRequest) {
var match = requestData.url.match(/angular\.min\.js/g);
if (match != null) {
networkRequest.abort();
}
};
page.open(home, function (status) {
if(status === "success"){
window.setTimeout((function() {
page.evaluate(function () {
/*stuff*/
});
}), 2000);
}
});
This version works entirely without reloading.

Read Meteor Session on a different page

I want to display a "Welcome back" message on the home page after the user performs a successful signIn. However, after I make a redirect with Router.go('home');, I can't read the Session within my Template.home.rendered = function().
Here is my code:
Login logic:
Meteor.loginWithPassword(username, password, function(err) {
if (err) {
showError();
} else {
Session.set('signInSuccess', true);
Router.go('home');
}
});
Template.home.rendered = function() {
console.log(Session.get('signInSuccess'));
if (Session.get('signInSuccess') == true) {
showWelcomeMessage();
Session.set('signInSuccess', null);
}
}
Any help would be greatly appreciated.
This is simply because Template.home.rendered is executed exactly once when your template is first inserted in the DOM (it may get executed again if the template is destroyed and reinserted, via the routing mechanism).
See rendered behavior here : http://docs.meteor.com/#template_rendered
Try wrapping your verification code inside an autorun :
Template.home.rendered=function(){
// setup a reactive computation to watch for Session variable modification
this.autorun(functon(){
// using Session.equals is better than checking against Session.get
// see http://docs.meteor.com/#session_equals
if(Session.equals("signInSuccess",true)){
showWelcomeMessage();
Session.set("signInSuccess",false);
}
});
};

Angular Js $scope

When establishing a controller, and setting the $scope to use a factory method (for GETs and POSTs), during the page load process, my POSTs are fired. Below is an example of the code. To fix this, I wrapped the "POST" in a jQuery click event function and everything works smoothly. Below is the code.
In the controller (app.js):
demoApp.controller('SimpleController', function ($scope, simpleFactory) {
$scope.customers = [];
init();
function init() {
$scope.departments = simpleFactory.getDepartments();
}
// Works fine
$('#myButton').click(function () {
simpleFactory.postDepartments();
});
// When setting the "scope" of a controller, during page load the scope factory method is fired off!
// seems like a defect.
//$scope.addDepartment = simpleFactory.postDepartments();
});
So, what is going on here is that if I uncomment the $scope.addDepartment = ... on page load, the postDepartments() factory method is called. This is not the desired behavior. Here is how I have the Html Dom element wired:
<button id="myButton" data-ng-click="addDepartment()">Add Department</button>
So, if I uncomment, like I said above, it adds the department before the user even clicks the button. However, approaching it the jQuery way, there is no issue.
Is this a known bug? Is this the intended functionality? Also, see the factory below, maybe the problem is there?
demoApp.factory('simpleFactory', function ($http) {
var departments = [];
var factory = {};
factory.getDepartments = function () {
$http.get('/Home/GetDepartments').success(function (data) {
for (var i = 0; i < data.length; i++) {
departments.push({ desc: data[i].desc, id: data[i].id });
}
})
.error(function () {
$scope.error = "An Error has occured while loading posts!";
$scope.loading = false;
});
return departments;
};
factory.postDepartments = function () {
$http.post('/Home/PostDepartment', {
cName: 'TST',
cDescription: 'Test Department'
}).success(function (data) {
departments.push({ desc: 'Test Department', id: departments.length + 1 });
})
.error(function () {
$scope.error = "An Error has occured while loading posts!";
$scope.loading = false;
});
return departments;
};
return factory;
});
Try this:
$scope.addDepartment = function() {
return simpleFactory.postDepartments();
}
This will also allow you to pass in arguments in the future, should you decide to. The way you originally had it, you were both assigning the function and calling it at the same time.
Then, you can use it in ngClick:
<button ng-click="addDepartment()">Add Department</button>
Don't use the jQuery click method in your controller, it defeats the purpose of separating the concerns into models, views, controllers, etc. That's what directives are for.

Categories