Meteor Iron-Router force page refresh - javascript

I just recently started working with Meteor and Iron Router, so I'm having some issues.
I am looking to have a very basic website and am nearly there but when it comes to reusing one of the templates for various directories, the page doesn't refresh which causes it to show the previous page despite the URL showing the correct page.
Once I hit refresh on the browser then the page will actually reload with the correct page, but I would rather not have to always refresh the page and would like to simply just have to click on a link and get the correct information.
I have attempted some of the solutions that I have seen pertaining to similar issues, but they all seemed to be a bit more unique than mine. I have included my .js file from meteor.
Router.route('/', function () {
this.render('iotprofiler');
});
Router.route('index.html', function () {
this.render('iotprofiler');
});
Router.route('/device(.*)', function () {
//document.location.reload(true);
this.render('profile');
});
if(Meteor.isClient){
//this code only runs on the client
var directory = Iron.Location.get().path;
var start = directory.lastIndexOf("/");
var stop = directory.search(".html");
var parseddir = directory.slice(start + 1,stop);
console.log(parseddir);
Template.iotprofiler.helpers({
'device': function(){
return DeviceList.find();
}
});
Template.profile.helpers({
'iotdevice': function(){
return DeviceList.find({model: parseddir});
}
});
}

Your problem is that parseddir is not reactive.
A solution is to follow the doc rendering template with data for iron router.
Just give parseddir as data to the profile template when you render it and in your helper use this.parseddir to get the actual data.

Related

Load scripts through all components in Angular 2

I have been using Angular 2 with AdminLTE which needs to run some scripts to load properly. So I have added them in in my .anglular-cli.json:
"scripts": [
"../node_modules/jquery/dist/jquery.min.js",
"../node_modules/bootstrap/dist/js/bootstrap.min.js",
"../node_modules/admin-lte/dist/js/adminlte.min.js",
"../node_modules/moment/min/moment.min.js"
],
Unfortunately, this does not work all time. The page loads fine the first time but when I route to another page, scripts are not reloaded for the component template.
I could not find any information about this which is very surprising for me since I thought it would be a general problem! I might be totally lost with this!
A simple solution I found was just to add a window.location.href = '...' to whatever link you are opening after login. Heres my function for the when the login button is clicked.
this.authService.authenticateMember(member).subscribe(data => {
if (data.success) {
...
window.location.href = '/'
...
} else {
...
}
}
So if you are using authentication then you can put that above code at the end of your login success response and it will refresh the page aswell as take the user to wherever they are going after a successful login.
This is not the best solution but it is the simplest one i can think of that dosent require too many changes. Hope it helps :)
You can remove and recreate your script elements in DOM every time you need, like this:
document.getElementById("myScript").remove();
var testScript = document.createElement("script");
testScript.setAttribute("id", "myScript");
testScript.setAttribute("src", "assets/js/script.js");
document.body.appendChild(myScript);
I posted a question in GitHub where I explain how to do it.

How to Handle redirects in Node.JS with HorsemanJs and PhantomJS

I´ve recently started using horseman.js to scrap a page with node. I can´t figure out how exactly it works and I can´t find good examples on the internet.
My main goal is to log on a platform and extract some data. I´ve managed to do this with PhantomJS, but know I want to learn how to do it with horseman.JS.
My code should open the login page, fill the login and password inputs and click on the "login" button. Pretty easy so far. However, after clicking on the "login" button the site makes 2 redirects before loading the actual page where I want to work.
My problem is that I don´t know how to make my code wait for that page.
With phantomJS I had a workaround with the page URL. The following code shows how I´ve managed to do it with phantomJS and it works just fine:
var page = require('webpage').create();
var urlHome = 'http://akna.com.br/site/montatela.php?t=acesse&header=n&footer=n';
var fillLoginInfo = function(){
$('#cmpLogin').val('mylogin');
$('#cmpSenha').val('mypassword');
$('.btn.btn-default').click();
};
page.onLoadFinished = function(){
var url = page.url;
console.log("Page Loaded: " + url);
if(url == urlHome){
page.evaluate(fillLoginInfo);
return;
}
// After the redirects the url has a "sid" parameter, I wait for that to apear when the page loads.
else if(url.indexOf("sid=") >0){
//Keep struggling with more codes!
return;
}
}
page.open(urlHome);
However, I can´t find a way to handle the redirects with horseman.JS.
Here is what I´ve been trying with horseman.JS without any success:
var Horseman = require("node-horseman");
var horseman = new Horseman();
var urlHome = 'http://akna.com.br/site/montatela.php?t=acesse&header=n&footer=n';
var fillLoginInfo = function(){
$('#cmpLogin').val('myemail');
$('#cmpSenha').val('mypassword');
$('.btn.btn-default').click();
}
var okStatus = function(){
return horseman.status();
}
horseman
.open(urlHome)
.type('input[name="cmpLogin"]','myemail')
.type('input[name="cmpSenha"]','mypassword')
.click('.btn-success')
.waitFor(okStatus, 200)
.screenshot('image.png')
.close();
How do I handle the redirects?
I'm currently solving the same problem, and my best solution so far is to use the waitForSelector method to target something on the final page.
E.g.
horseman
.open(urlHome)
.type('input[name="cmpLogin"]','myemail')
.type('input[name="cmpSenha"]','mypassword')
.click('.btn-success')
.waitForSelector("#loginComplete")
.screenshot('image.png')
.close();
Of course you have to know the page you're waiting for to do this.
If you know there are two redirects, you can use the approach of .waitForNextPage() twice. A naive approach if you didn't know how many redirects to expect would be to chain these until a timeout is reached (I don't recommend this as it will be slow!),
Perhaps a cleverer way, you can also use on events to capture redirects, like .on('navigationRequested') or .on('urlChanged').
Although it doesn't answer your question directly, this link may help: https://github.com/ariya/phantomjs/issues/11507

Force view to reload tvml content on Apple TV/tvos

I have been working on dynamically generating tvml-templates with very frequently changing content for a tvOS app on Apple TV. Generating the templates works fine, however I have not been able to get the app to update/reload the content of a template when navigating back and forth between views or leaving and reentering the app. Only rebooting seems to reload the tvml template.
Your template will refresh itself automatically whenever you manipulate the TVML within the template document.
If you maintain a reference to the document like so:
var myDoc;
resourceLoader.loadResource(templateURL,
function(resource) {
if (resource) {
myDoc = self.makeDocument(resource);
});
}
you can manipulate the TVML using myDoc and your view will automatically change.
So if your template document includes a "collectionList" and you were to run this code:
//Removes the child elements of the first collectionList
var collectionLists = myDoc.getElementsByTagName("collectionList");
var collectionList = collectionLists.item(0);
while (collectionList.firstChild) {
collectionList.removeChild(collectionList.firstChild);
}
your view would no longer display the UI elements within the collectionList. The view will refresh itself the moment the code is run.
The answer by #shirefriendship pointed my in the right direction (thank you!). As another example, if you wanted to change the text of a single element in a template (such as the description), you would need to use the innerHTML property:
function changeDescription(incomingString) {
console.log("inside the change description function")
if (incomingString) {
var theDescription = myDoc.getElementsByTagName("description").item(0);
theDescription.innerHTML = incomingString;
}
}
This changes the description immediately to the viewer.
If you are using atvjs framework, you can easily create and navigate to dynamic pages which are regenerated while navigating.
ATV.Page.create({
name: 'home',
url: 'path/to/your/api/that/returns/json',
template: your_template_function
});
// navigate to your page
ATV.Navigation.navigate('home');
Set this in the header of your API:
Cache-Control:no-cache
Got it from Apple Docs: https://developer.apple.com/library/tvos/documentation/General/Conceptual/AppleTV_PG/YourFirstAppleTVApp.html
IMPORTANT
When serving JavaScript and XML files from your web server, you often
need to ensure that any changes to your pages are always visible to
the client app. To do this, your server must ensure that the client
does not cache any of the pages. When your server responds to an HTTP
request for a page that should not be cached, the server should
include Cache-Control:no-cache in the HTTP response header.

ReportViewer Web Form causes page to hang

I was asked to take a look at what should be a simple problem with one of our web pages for a small dashboard web app. This app just shows some basic state info for underlying backend apps which I work heavily on. The issues is as follows:
On a page where a user can input parameters and request to view a report with the given user input, a button invokes a JS function which opens a new page in the browser to show the rendered report. The code looks like this:
$('#btnShowReport').click(function () {
document.getElementById("Error").innerHTML = "";
var exists = CheckSession();
if (exists) {
window.open('<%=Url.Content("~/Reports/Launch.aspx?Report=Short&Area=1") %>');
}
});
The page that is then opened has the following code which is called from Page_Load:
rptViewer.ProcessingMode = ProcessingMode.Remote
rptViewer.AsyncRendering = True
rptViewer.ServerReport.Timeout = CInt(WebConfigurationManager.AppSettings("ReportTimeout")) * 60000
rptViewer.ServerReport.ReportServerUrl = New Uri(My.Settings.ReportURL)
rptViewer.ServerReport.ReportPath = "/" & My.Settings.ReportPath & "/" & Request("Report")
'Set the report to use the credentials from web.config
rptViewer.ServerReport.ReportServerCredentials = New SQLReportCredentials(My.Settings.ReportServerUser, My.Settings.ReportServerPassword, My.Settings.ReportServerDomain)
Dim myCredentials As New Microsoft.Reporting.WebForms.DataSourceCredentials
myCredentials.Name = My.Settings.ReportDataSource
myCredentials.UserId = My.Settings.DatabaseUser
myCredentials.Password = My.Settings.DatabasePassword
rptViewer.ServerReport.SetDataSourceCredentials(New Microsoft.Reporting.WebForms.DataSourceCredentials(0) {myCredentials})
rptViewer.ServerReport.SetParameters(parameters)
rptViewer.ServerReport.Refresh()
I have omitted some code which builds up the parameters for the report, but I doubt any of that is relevant.
The problem is that, when the user clicks the show report button, and this new page opens up, depending on the types of parameters they use the report could take quite some time to render, and in the mean time, the original page becomes completely unresponsive. The moment the report page actually renders, the main page begins functioning again. Where should I start (google keywords, ReportViewer properties, etc) if I want to fix this behavior such that the other page can load asynchronously without affecting the main page?
Edit -
I tried doing the follow, which was in a linked answer in a comment here:
$.ajax({
context: document.body,
async: true, //NOTE THIS
success: function () {
window.open(Address);
}
});
this replaced the window.open call. This seems to work, but when I check out the documentation, trying to understand what this is doing I found this:
The .context property was deprecated in jQuery 1.10 and is only maintained to the extent needed for supporting .live() in the jQuery Migrate plugin. It may be removed without notice in a future version.
I removed the context property entirely and it didnt seem to affect the code at all... Is it ok to use this ajax call in this way to open up the other window, or is there a better approach?
Using a timeout should open the window without blocking your main page
$('#btnShowReport').click(function () {
document.getElementById("Error").innerHTML = "";
var exists = CheckSession();
if (exists) {
setTimeout(function() {
window.open('<%=Url.Content("~/Reports/Launch.aspx?Report=Short&Area=1") %>');
}, 0);
}
});
This is a long shot, but have you tried opening the window with a blank URL first, and subsequently changing the location?
$("#btnShowReport").click(function(){
If (CheckSession()) {
var pop = window.open ('', 'showReport');
pop = window.open ('<%=Url.Content("~/Reports/Launch.aspx?Report=Short&Area=1") %>', 'showReport');
}
})
use
`$('#btnShowReport').click(function () {
document.getElementById("Error").innerHTML = "";
var exists = CheckSession();
if (exists) {
window.location.href='<%=Url.Content("~/Reports/Launch.aspx?Report=Short&Area=1") %>';
}
});`
it will work.

How to index dynamic pages to google using html5 pushstate method?

I am building a fully jquery powered website, so i am loading all pages dynamically using ajax to achieve fancy transitions between pages and maximize user experience.
Here is my javascript code:
$(function() {
var path = _.compact(location.pathname.split("/"));
if(path.length<2){
path = 'home'
}else{
path = path[path.length-1];
}
activepage = path;
$('.nav a').click(function(e) {
href = $(this).attr("href");
loadContent(href);
// HISTORY.PUSHSTATE
window.history.pushState('', 'New URL: '+href, href);
e.preventDefault();
});
// THIS EVENT MAKES SURE THAT THE BACK/FORWARD BUTTONS WORK AS WELL
window.onpopstate = function(event) {
var path = _.compact(location.pathname.split("/"));
if(path.length<2){
path = 'home'
}else{
path = path[path.length-1];
}
loadContent(path);
};
});
function loadContent(url){
// USES JQUERY TO LOAD THE CONTENT
var adresa = absurl + "ajax/get_content";
$.ajax({
url: adresa,
contentType: 'application/json',
data: { url: url },
success: function(data) {
switch(url)
{
case "projects": $.projects({ data : data }); $.projects.init();
break;
case "home": $.homePage({ data : data }); $.homePage.init();
break;
default: console.log("nista");
}
}
});
}
Ajax function returns all data needed to build pages in the json format, then i initialize my custom plugin which builds the page using that json data.
All of that works perfectly fine as you can see on this LIVE EXAMPLE, including the browser history (back and forward).
But here is my problem... When the page is fully loaded the main container remains empty when i look at the source of the page. Also its empty when i try to fetch the page as google bot and i am pretty sure that these two are related.
As you can see on this example with the pretty much same code like i have, the source is being changed when you click on the links and it changes the page content as well, but without reloading the page.
My question is, what am I missing here and how to achieve the same effect? Am i missing some php code or what? I am struggling with this over the past few days, I've tried everything and i couldn't make it work.
Note: only home and project links are working for now...
Thanks a lot for all replies!
pushState lets you change the local part of the URI when you update the page contents with Ajax.
For every URI you create that way, allow the server to build the same page without any dependency on JavaScript.
This will:
Give better performance when visitors enter the site by following a deep link
Allow the site to work without JavaScript (including for search engine robots)
Complementing the #Quentin's answer, you need to identify in the PHP if the content is being loaded via ajax or not.
If it isn't, you have to display the full content of the page being requested, including header, footer and the content of the page.

Categories

Resources