Load scripts through all components in Angular 2 - javascript

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.

Related

Meteor Iron-Router force page refresh

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.

Chrome extension to refresh a page every minute and run a (javascript) script every time it refreshes

What I want:
My propose is to check if new content was added in a page (that I do not own), so I was thinking to make a script that save the last content added in a cookie and refresh the page every minute: If the cookie doesn't match the last content added, that would mean there is new content and I would receive a notification.
Let's try with pseudocode:
main_file:
include: functions.js;
cookie last_content_added= get_first_paragraph();
//Refresh script
do (every_minute){
page_reload();
}
when.page.reload.complete {
run script_check_content
}
functions.js
script_check_content{
var content_check = get_first_paragraph();
if (content_check == cookie[last_content_added])
{
//do nothing
}
else{
//new content was added
play.notification.mp3
cookie[last_content.added] = get_first_paragraph();
}
}
Am I not thinking in an easier solution for what I'm looking for?
I'm new to chrome extensions, if you could separate the code in different files like it was a real extension, I would appreciate very much.
I recommend to use 'chrome.tabs.query', use this to get all tabs that have the specified properties or all tabs if no properties are specified and 'chrome.tabs.executeScript' to inject the javascript code into a page that calls 'window.location.reload(). to refresh the page.
Here's a sample code to get the current tab and reload it using chrome.tab methods:
chrome.tabs.query({active: false, currentWindow: true}, function (arrayOfTabs) {
var code = 'window.location.reload();';
chrome.tabs.executeScript(arrayOfTabs[0].id, {code: code});
});
Also, include 'onCompleted' listener to listen when it is completely loaded and initialized.
chrome.webNavigation.onCompleted.addListener(function callback).
Take a look at MutationObserver, it provides a way to react to changes in a DOM. You can provide a callback to react to DOM changes and don't need to use a timer.

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

Updating content in a Google Apps Script sidebar without reloading the sidebar

I am using the following Google Apps Script code to display content in a custom sidebar of my spreadsheet while the script runs:
function test() {
var sidebarContent = '1<br>';
updateSidebar(sidebarContent);
sidebarContent += '2<br>';
updateSidebar(sidebarContent);
sidebarContent += '3';
updateSidebar(sidebarContent);
}
function updateSidebar(content) {
var html = HtmlService.createHtmlOutput(content)
.setSandboxMode(HtmlService.SandboxMode.IFRAME)
.setTitle('Sidebar')
.setWidth(250);
SpreadsheetApp.getUi().showSidebar(html);
}
It works, but each time the updateSidebar() function runs, the sidebar blinks when loading in the new content.
How can I program this to update the content of the sidebar more efficiently, thus removing the blink?
I'm assuming that SpreadsheetApp.getUi().showSidebar(html); should really only be run once, at the beginning, and the subsequent updates to the content should be handled by Javascript in a .js file.
But I don't know how to get the sidebarContent variable from Javascript code running client-side in the user's browser.
Also, I know this must be possible, because I just saw this post on the Google Apps Developer Blog today about an app that uses a custom sidebar, and the .gif towards the end of the article shows a nicely-animated sidebar that's being updated in real-time.
I believe the solution for this situation is to actually handle the flow of the server-side script from the client-side. That is the only way I can think of right now to pass data to the client side from the server without re-generating the HTML.
What I mean by this is that you would want to make the calls to the server-side functions from the client, and have them return a response as a success handler to the client. This means that each action that needs to be logged will need to be made into its own function.
Ill show you a quick example of what I mean.
Lets say your server-side GAS code looked like this:
function actionOne(){
...insert code here...
return true;
}
function actionTwo(){
...insert code here...
return true;
}
And so on for as many actions need to be executed.
Now, for your .html file, at the bottom you would have javascript looking something like this:
<script>
callActionOne();
function callActionOne(){
google.script.run.withSuccessHandler(callActionTwo).actionOne();
}
function callActionTwo(){
...update html as necessary to indicate that the first action has completed...
google.script.run.withSuccessHandler(actionsComplete).actionTwo();
}
function actionsComplete(){
..update html to indicate script is complete...
}
</script>
It is a bit more complex than is ideal, and you might need to use the CacheService to store some data in between actions, but it should help you with your problem.
Let me know if you have any questions or if this doesn't fit your needs.

Angular: redirecting /#%21/ to /#!/

In emails that we send to users, we include links to Angular app like the following:
http://example.com/#!/mypage
We've noticed that some email clients or browsers, for one reason or another, upon click direct the user to this instead:
http://example.com/#%21/mypage
Angular then throws the following error:
Uncaught Error: [$location:ihshprfx] Invalid url "http://example.com/#%21/mypage", missing hash prefix "#!".
http://errors.angularjs.org/1.3.0-beta.10/$location/ihshprfx
We are using $locationProvider.hashPrefix('!');. I'm trying to find a way to detect instances where $location is /#%21/ rather than /#!/ and then redirect properly, but I can't find a way to detect and/or get Angular to do this. What is the proper way to do this?
Ended up finding a better answer here:
Adding a hash prefix at the config phase if it's missing
Using $locationChangeStart didn't work because angular threw the error during initialization, so $locationChangeStart was never tripped.
Instead, I went with the following approach:
<head>
<!-- Change #%21 to #! on first load -->
<script type="text/javascript">
var loc = window.location.href;
if (loc.indexOf('#%21') > -1 && loc.indexOf('#!') === -1 ) {
window.location.href = loc.replace("#%21", "#!");
}
</script>
<!-- More stuff ... -->
</head>
<body>...
This (a) allows me to rewrite the URL before we ever hit Angular, and (b) makes sure we only rewrite it the first time the app is loaded, rather than any time there's a location change--just in case at some point in the future we deliberately write a change that includes a #%21.
Might not be the most elegant way to go about solving your problem, but you could catch the $locationChangeStart event and then conditionally redirect the user with the $location service based on what the nature of the URL is.
For example:
$rootScope.$on('$locationChangeStart', function(event, newUrl, oldUrl) {
// ...
});

Categories

Resources