Update Data from Calculator - NodeJS + AngularJS - javascript

I am new to JS development. I found a nodejs calculator project on github that I've been manipulating.
My Problem: In my calculator, I'm trying to combine all of my results together. However, the data of my old entries are still present, I would like to remove these old entries and have it update instead with the most up-to-date entry.
I know it has something to do with data-ng-repeat (shown in my index code below), but I've tried other directives and they haven't worked. Is there something I need to change in my code to use a different directive?
Here's what I am working with, everything works well until the last screenshot:
Widget calculator
https://imgur.com/a/2ebpyym
Specific Widget Selection
https://imgur.com/a/STYeLcF
Entering QTY of Widgets
https://imgur.com/a/B5ii32J
Calculation Result #1 (1 Sheet is worth 8 Widgets)
https://imgur.com/a/CUouHAt
Problem: Calculation Result #2
https://imgur.com/a/XJrclUY
In the above link, I would prefer if the "62.5" in the "Combined Sheets Needed" section is replaced by "93.75"
Code
server.js
'use strict';
const express = require('express');
const app = express();
let PORT = process.env.PORT || 3000;
console.log('hello1')
let operators = [
{name:'24x24 Widget', symbol:'24x24 Widget'}
];
function calculate(operator, value1, value2) {
if ( operator == '24x24 Widget' ) return value1 /8 + " sheets";
}
app.use(express.static(__dirname + '/build'));
app.use(require('body-parser').json());
app.use((req, res, next) => {
// res.header('Access-Control-Allow-Origin', 'http://localhost:3000');
res.header('Access-Control-Allow-Origin', 'https://mean-calculator.herokuapp.com/calculator');
res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');
next();
});
app.listen(PORT, () => {
console.log('server started on port', PORT);
});
var array = [];
app.route('/calculator')
.get((req, res) => {
res.json({
operators
});console.log('hello in route')
array = [];
})
.post((req, res) => {
let operator = req.body.operator.name;
let value1 = req.body.value1;
let result = calculate(operator, value1);
array.push(value1/8);
console.log(array);
var sum = array.reduce(function(a, b) { return a + b; }, 0);
console.log(sum, 'this is the sum');
let doubleresult = calculate(operator, value1*2)
res.json({
result: {
operator: req.body.operator.symbol,
value1,
result,
sum
}
});
});
index.html
(Check comment: <!-- Combining Data Here-->)
<!DOCTYPE html>
<html data-ng-app="App">
<head>
<meta charset="utf-8">
<link href='https://fonts.googleapis.com/css?family=Open+Sans|Lora|Lato:700' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="main.css" charset="utf-8">
<title>Widget Calculator</title>
</head>
<body data-ng-controller="AppController as appCtrl"></body>
<h1>Solve for Material Needed for Widgets</h1>
<div class="solve">
<h2 data-ng-show="appCtrl.error" class="error">{{appCtrl.error}}</h2>
<form method="post">
<h2>Select a Widget</h2>
<select data-ng-model="operator" data-ng-options="operatorOption.name for operatorOption in appCtrl.operators">
<option value="">-- choose Widget --</option>
</select>
<h2>Select QTY</h2>
<input data-ng-model="value1" type="number" placeholder="1st Number">
<span>{{operator.symbol}}</span>
<span></span>
<button data-ng-click="appCtrl.calculate(operator, value1, value2); value1=undefined; value2=undefined; operator=undefined" type="button">Calculate</button>
</form>
</div>
<div data-ng-show="appCtrl.results.length">
<h1>Results</h1>
<div class="result">
<h2 data-ng-repeat="result in appCtrl.results">{{result.value1}} {{result.operator}} = {{result.result}}</h2>
</div>
</div>
<!-- Combining Data Here-->
<div data-ng-show="appCtrl.results.length">
<h1>Combined Sheets Needed</h1>
<div class="result combined">
<h2 data-ng-repeat="result in appCtrl.results">{{result.sum}}</h2>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.6/angular.js" charset="utf-8"></script>
<script src="app.js" charset="utf-8"></script>
</body>
</html>
app.js
var app = angular.module('App', []);
app.controller('AppController', ['$http', function($http) {
var apiRoute = 'http://localhost:3000/calculator';
var _this = this;
_this.results = [];
_this.operators = [];
$http.get(apiRoute)
.then(function(res) {
_this.operators = res.data.operators;
}, function(res) {
console.log(res);
});
_this.calculate = function(operator, value1, value2) {
_this.error = validate(operator, value1, value2);
if (!_this.error) {
$http.post(apiRoute, {operator, value1, value2})
.then(function(res) {
_this.results.push(res.data.result);
}, function(res) {
console.log(res);
});
}
}
}]);
function validate(operator, value1, value2) {
if (!operator) return 'Please select an operator.';
if ((!value1 && value1 != 0) || (!value1 && value1 != 0)) return 'Please enter two numbers.';
return null;
}

Related

Select2 triggering change event

I, not so long ago, went ahead and built an html dependent dropdown which pulls it's data from an array in the js. The dependencies worked perfectly fine until I realized that I needed to add a search function to the dropdown.
I went through different alternatives and to me the simplest option was to use select2 plugin. The problem I am having is that when using select2, it doesn't seem to be triggering the EventListener (Line 43 in JS) I had previously setup for the regular select.
Find below what I have attempted:
HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/select2#4.0.13/dist/css/select2.min.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/select2#4.0.13/dist/js/select2.min.js"></script>
<title>Document</title>
</head>
<body>
<select id ="level1" style='width: 300px;'></select>
<select id ="level2" style='width: 300px;'></select>
<select id ="level3" style='width: 300px;'></select>
<hr>
<select id ="level4" disabled></select>
<select id ="level5" disabled></select>
<select id ="level6" disabled></select>
<select id ="level7" disabled></select>
<hr>
<h1 id ="level8"></h1>
<script src="betterdd.js"></script>
</body>
</html>
JS: (Select options are found in var myData = [...])
class DropDown {
constructor(data){
this.data = data;
this.targets = [];
}
filterData(filtersAsArray){
return this.data.filter(r => filtersAsArray.every((item,i) => item === r[i]));
}
getUniqueValues(dataAsArray,index){
const uniqueOptions = new Set();
dataAsArray.forEach(r => uniqueOptions.add(r[index]));
return [...uniqueOptions];
}
populateDropDown(el,listAsArray){
el.innerHTML = "";
listAsArray.forEach(item => {
const option = document.createElement("option");
option.textContent = item;
el.appendChild(option);
});
}
createPopulateDropDownFunction(el,elsDependsOn){
return () => {
const elsDependsOnValues = elsDependsOn.length === 0 ? null : elsDependsOn.map(depEl => depEl.value);
const dataToUse = elsDependsOn.length === 0 ? this.data : this.filterData (elsDependsOnValues);
const listToUse = this.getUniqueValues(dataToUse, elsDependsOn.length);
this.populateDropDown(el,listToUse);
}
}
add(options){
//{target: "level2", dependsOn: ["level1"] }
const el = document.getElementById(options.target);
const elsDependsOn = options.dependsOn.length === 0 ? [] : options.dependsOn.map(id => document.getElementById(id));
const eventFunction = this.createPopulateDropDownFunction (el, elsDependsOn);
const targetObject = { el: el, elsDependsOn: elsDependsOn,func: eventFunction};
targetObject.elsDependsOn.forEach(depEl => depEl.addEventListener("change",eventFunction));
this.targets.push(targetObject);
return this;
}
initialize(){
this.targets.forEach(t => t.func());
return this;
}
eazyDropDown(arrayOfIds){
arrayOfIds.forEach((item,i) =>{
const option = {target: item, dependsOn: arrayOfIds.slice(0,i) }
this.add(option);
});
this.initialize();
return this;
}
}
var dd = new DropDown(myData).eazyDropDown(["level1","level2","level3","level4","level5","level6","level7","level8"])
add the following line inside add method :
const eventFunction = this.createPopulateDropDownFunction (el, elsDependsOn);
el.addEventListener("change", (e) => {
eventFunction();
console.log(e.target.value)
})
and remove the following line:
targetObject.elsDependsOn.forEach(depEl => depEl.addEventListener("change",eventFunction));

Update a Variable Dynamically with flask app

I am trying to create a script with flask that increments or decrements a value by ten by clicking a button. I alraeady have a script that does this in the backend, but I am having trouble displaying and dynamically updating this value in the frontend. Basically, I want to change this value in the frontend and backend at the same time without refressing the page.
Here is the Backend Code (shortened to include the page in question):
app.py - The Flask App
from flask import Flask, render_template, url_for, request, jsonify
app = Flask(__name__)
#motor = Motor(17, 18)
def setBPM(current, change=0):
return ((current < 200) & (change > 0))*(current+change) + ((current > 30) & (change < 0))*(current+change)
#app.route('/pulse')
def pulse():
return render_template("pulse.html")
#app.route('/pulseUP', methods=['POST'])
def pulseUp():
BPM = setBPM(BPM, 10)
return (render_template('pulse.html', get_BPM_var=BPM))
#app.route('/pulseDOWN', methods=['POST'])
def pulseDwn():
BPM = setBPM(BPM, -10)
return (render_template('pulse.html', get_BPM_var=BPM))
#app.context_processor
def get_BPM_var():
return dict(get_BPM_var=BPM)
if __name__ == "__main__":
app.run(debug=True)
Frontend - pulse.html
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=800px, inital-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="{{ url_for('static', filename='css/main.css') }}"
</head>
<body>
<div class="parent">
<div class="child">
<div id="grid-pulse">
<div class="cell-pulse">
<form action="/pulseUP/" method="post"><input type="submit" value="+" /></form>
</div>
<div class="cell-pulse"></div>
<div class="cell-pulse">
<div class="numbkgnd">
<h3 id="BPMID">{{ get_BPM_var }}
BPM</h3>
</div>
</div>
<div class="cell-pulse"></div>
<div class="cell-pulse">
<form action="/pulseDOWN/" method="post"><input type="submit" value="-" /></form>
</div>
<div class="cell-pulse"></div>
</div>
</div>
</div>
<script>
$("#BPMID").keyup(function () {
var text = $(this).val();
$.ajax({
url: "/pulse",
type: "get",
data: { jsdata: text },
success: function (response) {
$("#BPMID").html(response);
},
error: function (xhr) {
}
});
});
</body>
</html>
I tried to use ajax to update the value, but I am not familair with javascript in the slightest. Any help would be greatly apprieciated!!
My example is based on a range slider whose value corresponds to the speed sent to the server. The value can be increased and decreased in increments of 10.
When a change event is triggered, the browser sends an AJAX POST type request to the server using the Fetch API. The request in JSON format contains the current value of the slider.
The server sets the received value as long as it is within the permitted range and replies in JSON format with the current speed.
After receiving the answer, the output in the browser is now adjusted, i.e. the value is output as text and set as the new value of the slider.
In addition to the slider, two buttons can also be used to set the value. Pressing it sets the slider's value and triggers its change event. After that, the process remains the same.
from flask import (
Flask,
jsonify,
render_template,
request
)
class Motor:
def __init__(self):
self._rpm = 30
#property
def rpm(self):
return self._rpm
#rpm.setter
def rpm(self, value):
if 30 <= value <= 200:
self._rpm = value
else:
raise ValueError('Value range must be between 30 and 200.')
app = Flask(__name__)
motor = Motor()
#app.route('/')
def index():
v = motor.rpm
return render_template('index.html', **locals())
#app.post('/adjust-speed')
def adjust_speed():
v = motor.rpm
try:
motor.rpm = int(request.get_json(force=True).get('v'))
v = motor.rpm
finally:
return jsonify(**locals())
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Control</title>
</head>
<body>
<input type="range" min="30" max="200" value="{{ v }}" step="10" id="speed">
<p>Velocity: <output id="value">{{ v }}</output></p>
<button id="btn-dec">-</button>
<button id="btn-acc">+</button>
<script type="text/javascript">
(() => {
/** Send the expected speed to the server. */
const adjustSpeed = async (value) => {
const data = await fetch('/adjust-speed', {
method: 'post',
body: JSON.stringify({ v: value })
}).then(resp => resp.ok && resp.json());
if (!data || !data.v) throw new Error('Error adjusting speed.');
return data.v;
};
const outputValue = document.getElementById('value');
const speedSlider = document.getElementById('speed');
speedSlider.addEventListener('change', async function() {
// Send the slider's value to the server and
// output the actual speed obtained.
try {
const v = await adjustSpeed(Number(this.value));
this.value = v;
outputValue.innerText = v;
} catch(err) {
console.error(err);
}
});
const buttonAcc = document.getElementById('btn-acc');
buttonAcc.addEventListener('click', () => {
// Set the new value of the slider and trigger the change event.
const value = Number(speedSlider.value), step = Number(speedSlider.step);
speedSlider.value = value + step;
speedSlider.dispatchEvent(new Event('change'));
});
const buttonDec = document.getElementById('btn-dec');
buttonDec.addEventListener('click', () => {
// Set the new value of the slider and trigger the change event.
const value = Number(speedSlider.value), step = Number(speedSlider.step);
speedSlider.value = value - step;
speedSlider.dispatchEvent(new Event('change'));
});
})();
</script>
</body>
</html>
If you don't like the control provided by the slider, you can also control the speed directly using the buttons. In this case, the following variant is possible.
#app.post('/accelerate')
def accelrate():
v = motor.rpm
try:
motor.rpm += int(request.get_json(force=True).get('a'))
v = motor.rpm
finally:
return jsonify(**locals())
const accelerate = async (value) => {
const data = await fetch('/accelerate', {
method: 'post',
body: JSON.stringify({ a: value })
}).then(resp => resp.ok && resp.json());
if (!data || !data.v) throw new Error('Error adjusting speed.');
return data.v;
};
const outputValue = document.getElementById('value');
const buttonAcc = document.getElementById('btn-acc');
buttonAcc.addEventListener('click', async () => {
try {
const v = await accelerate(10);
outputValue.innerText = v;
} catch(err) {
console.error(err);
}
});
const buttonDec = document.getElementById('btn-dec');
buttonDec.addEventListener('click', async () => {
try {
const v = await accelerate(-10);
outputValue.innerText = v;
} catch(err) {
console.error(err);
}
});

how to detect changed radio input value with ng-model when its value is initialised after fetching some data

i am fetching some data from the server and based on that i am initialising the ng-value of input which is shown after the data is fetched. But after that when I call a function with ng-change, console log doesn't show the changed value of the ng-model="chosedOption". It continues to print "Paytm Blance" even after selecting other radio buttons.
angular js file
var app = angular.module("formModule", []);
var formController = ($scope, $http) => {
$scope.chosedOption = "Paytm Balance";
$scope.amount = 10;
$scope.resJson = "";
$scope.payOptions = undefined;
$scope.proceed = (chosedOption) => {
console.log(chosedOption);
console.log($scope.chosedOption);
}
$scope.loadDoc = () => {
const orderId = Math.floor(Math.random() * 10000) + 100000;
const data = {
amount: $scope.amount,
orderId: orderId
}
$http.post("http://localhost:3200/intiate_transaction_api",data)
.then(response => {
$scope.resJson = JSON.stringify(response, undefined, 4);
console.log(response);
let data = {
txnToken: response.data.body.txnToken,
orderId: orderId
}
$http.post('http://localhost:3200/fetch_payment_option_api', data)
.then(response2 => {
$scope.resJson = JSON.stringify(response2, undefined, 4);
$scope.payOptions = response2.data.body.merchantPayOption.paymentModes;
})
})
}
}
app.controller("formController", formController);
app.filter('safeHtml', $sce => {
return function(val) {
return $sce.trustAsHtml(val);
}
})
html file
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="./style.css">
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.7.5/angular.min.js"></script>
<title>UI</title>
</head>
<body ng-app="formModule" ng-controller="formController">
<div class="result">
<div class="container">
<form name="amt" action="#"></form>
total amount<input type="text" id="amount" ng-model="amount" name="amount">
<button ng-click="loadDoc()">Pay</button>
</div>
</div>
<div id="payOtions" ng-if="payOptions">
<div ng-repeat="option in payOptions">
<label>
<div class="paymentOption" ng-class="">
<input name="payOption"
ng-change="proceed(option.displayName)"
ng-model="chosedOption" type="radio"
ng-value="option.displayName">
{{option.displayName}}
</div>
</label>
</div>
</div>
<pre><code id="demo" ng-bind-html="resJson | safeHtml"></code></pre>
<script src="./angularScript.js"></script>
</body>
</html>
output
can be checked here
The ng-change directive only listens to changes made by the user. It does not listen to changes made by the controller.
Any changes done by the controller should call the listening function from the controller.

Angular.js: Error: Module 'MyApp' is not available

I would like to use this plunk locally on my machine. However, when I either run it with the local Python server or http-server, I keep getting the following Error:
Uncaught Error: [$injector:modulerr] Failed to instantiate module myApp due to:
Error: [$injector:nomod] Module 'myApp' is not available! You either misspelled the module name or forgot to load it. If registering a module ensure that you specify the dependencies as the second argument.
My html file looks like this:
<!DOCTYPE html>
<html ng-app="myApp">
<head lang="en">
<meta charset="utf-8" />
<title>Custom Plunker</title>
<script scr="main.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.0/angular.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/PapaParse/4.1.1/papaparse.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/angular-file-upload/1.1.5/angular-file-upload.min.js"></script>
<link rel="stylesheet" href="main.css">
</head>
<body ng-controller="MyCtrl">
<h1>CSV</h1>
<div>
<input type="checkbox" ng-model="append">
Append to existing on drag & drop
</div>
<div class="drop-container" nv-file-drop nv-file-over uploader="uploader">
<textarea ng-model="csv" placeholder="Enter your CSV here, or drag/drop a CSV file"></textarea>
</div>
<h1>D3 Flare JSON</h1>
<div>
<input type="checkbox" ng-model="compact"> Compact
</div>
<div>
<input type="text" ng-model="tags.parent" placeholder="parent tag">
<input type="text" ng-model="tags.children" placeholder="children tag">
<input type="text" ng-model="tags.leaf" placeholder="leaf tag">
<input type="text" ng-model="tags.size" placeholder="size tag">
</div>
<textarea readonly ng-model="json"></textarea>
</body>
</html>
And the main.js file looks like this:
CSV to D3 Flare JSON converter in AngularJSPreview Edit Code
index.html
main.js
main.css
main.js
angular.module('myApp', ['angularFileUpload'])
.factory('FlareJson', ['$q', function($q) {
function updateTree(curr, arr, tags) {
if ((arr.length || 0) < 2) {
return;
}
if (!curr.hasOwnProperty(tags.children)) {
curr[tags.children] = [];
}
var elem;
if (arr.length == 2) {
elem = {};
elem[tags.leaf] = arr[0];
elem[tags.size] = arr[1];
curr[tags.children].push(elem);
} else {
curr[tags.children].some(function(e) {
if (e[tags.parent] == arr[0] || e[tags.leaf] == arr[0]) {
elem = e;
return true;
}
});
if (!elem) {
elem = {};
elem[tags.parent] = arr[0];
curr[tags.children].push(elem);
}
updateTree(elem, arr.slice(1), tags);
}
}
function buildJson(csv, compact, tags) {
var deferred = $q.defer();
var result = {};
result[tags.parent] = 'flare';
Papa.parse(csv, {
header: false,
dynamicTyping: true,
complete: function(csvArray) {
csvArray.data.forEach(function(line) {
if (line.length) {
updateTree(result, line, tags);
}
});
if (compact) {
deferred.resolve(JSON.stringify(result));
} else {
deferred.resolve(JSON.stringify(result, null, 2));
}
}
});
return deferred.promise;
}
return buildJson;
}])
.controller('MyCtrl', ['$scope', 'FileUploader', 'FlareJson',
function($scope, FileUploader, FlareJson) {
$scope.csv = "";
$scope.compact = false;
$scope.json = "";
$scope.tags = {
parent: 'skill',
children: 'children',
leaf: 'name',
size: 'level'
};
$scope.uploader = new FileUploader();
$scope.uploader.onAfterAddingFile = function(fileItem) {
var reader = new FileReader();
reader.onloadend = function(event) {
$scope.$apply(function() {
if ($scope.append) {
$scope.csv += event.target.result;
} else {
$scope.csv = event.target.result;
}
});
};
reader.readAsText(fileItem._file);
};
function update() {
FlareJson($scope.csv, $scope.compact, $scope.tags).then(function(json) {
$scope.json = json;
});
}
$scope.$watchGroup(['csv', 'compact'], update);
$scope.$watchCollection('tags', update);
}]);
I don't understand what I'm doing wrong. I already searched for similar error messages, but nothing that I found could help me to solve my problem.
You load your script file before angularjs file that's why you are getting this error.
So, Add your "main.js" file after "angular.js" file.
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.0/angular.js"></script>
<script scr="main.js"></script>
I believe it's because you're loading your main.js before you load Angular. Try putting your script at the end of the script definitions:
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.0/angular.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/PapaParse/4.1.1/papaparse.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/angular-file-upload/1.1.5/angular-file-upload.min.js"></script>
<script scr="main.js"></script>
Oh, solved! Turns out, that the following couple of first lines in main.js were causing the trouble:
CSV to D3 Flare JSON converter in AngularJSPreview Edit Code
index.html
main.js
main.css
main.js
I removed them from main.js, now it works - yuhuu! :)

AngularJS saving dynamic content to history

I'm new to AngularJS and I'm trying to make a home page that loads dynamic content from my database to create links. When I click one of those links on the home page, it sends a request to my node server and retrieves the appropriate data from the database and displays that on the partial view. When I'm on that partial view and I click the browser's back button to go back to the home page, the dynamic content that was originally loaded doesn't display. Below is my code. Why doesn't clicking the browser's back button redisplay the home page with the dynamic content?
index.html
<!doctype html>
<html lang="en" ng-app="phonecatApp">
<head>
<meta charset="utf-8">
<base href="/">
<title>My site</title>
<link rel="stylesheet" href="http://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css">
<link rel="stylesheet" href="bower_components/bootstrap/dist/css/bootstrap.css">
<link rel="stylesheet" href="css/app.css">
<link rel="stylesheet" href="css/animations.css">
<script src="bower_components/jquery/jquery.js"></script>
<script src="bower_components/angular/angular.js"></script>
<script src="bower_components/angular-animate/angular-animate.js"></script>
<script src="bower_components/angular-route/angular-route.js"></script>
<script src="bower_components/angular-resource/angular-resource.js"></script>
<script src="/js/animations.js"></script>
<script src="/js/controllers.js"></script>
<script src="/js/filters.js"></script>
<script src="/js/app.js"></script>
</head>
<body ng-controller="mainController">
<div class="container">
<nav class="navbar navbar-default" role="navigation">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="/" ng-click="home()">Home</a>
</div>
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
</ul>
<form class="navbar-form navbar-left" role="search">
<div class="form-group">
<input type="text" class="form-control" data-provide="typeahead" autocomplete="off" placeholder="foo, bar" ng-model="query">
</div>
</form>
<ul class="nav navbar-nav navbar-right">
</ul>
</div>
</div>
</nav>
</div>
<div class="view-container">
<div ng-view class="view-frame"></div>
</div>
</body>
</html>
phone-detail.html
<div class="phone-images">
<img ng-src="{{thing.imageUrl}}" dclass="phone">
</div>
<h1> {{ things[0].name }} </h1>
<iframe id="viddy" width="560" height="315" ng-src="{{ things[0].embed }}" frameborder="0" allowfullscreen autoplay="1" ></iframe>
<p>source:</p>
<p>{{ things[0].vid }}</p>
</div>
phone-list.html
<div class="container-fluid">
<div class="row">
<div class="col-md-10">
<!--Body content-->
<div>
<div ng-if="things.length>1">
<ul class="phones">
<li ng-repeat="foo in things | filter:query"
class="thumbnail phone-listing">
<img ng-src="{{foo.imageUrl}}">
{{foo.name}}
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
//controller.js
'use strict';
/* Controllers */
var coreControl = angular.module('prjController', []);
coreControl.controller('mainController', ['$scope', '$http', '$sce', '$locationProvider'
function($scope, $http, $sce, $locationProvider)
{
//$scope.$on('$routeChangeSuccess', function(req, res) {console.log($route.current.params);})
$scope.formData = {};
$scope.things = [];
$scope.maxThings = 0;
$http.get('/things')
.success(function(data)
{
$scope.things = data;
$scope.maxThings = $scope.things.length;
console.log(data);
})
.error(function(data)
{
console.log('Error: ' + data);
});
$scope.home = function()
{
$http.get('/things')
.success(function(data)
{
$scope.things = data;
$scope.maxThings = $scope.things.length;
console.log(data);
})
.error(function(data)
{
console.log('Error: ' + data);
});
}
$scope.search = function(thing)
{
$http.get('/thing/'+thing, $scope.formData)
.success(function(data)
{
$scope.formData = {};
$scope.things = data;
$scope.msg = "Recommend a video."
$scope.noMatch = false;
if($scope.things.length == 0)
{
$scope.noMatch = true;
}
$scope.things[0].embed = $sce.trustAsResourceUrl($scope.things[0].embed+"?autoplay=0&showinfo=0&controls=0&loop=1");
document.getElementById('viddy').src = document.getElementById('viddy').src;
console.log(data);
})
.error(function(data)
{
console.log('Error: ' + data);
});
}
}]);
//app.js
'use strict';
var phonecatApp = angular.module('phonecatApp', [
'ngRoute',
'phonecatAnimations',
'prjController'
]);
phonecatApp.config(['$routeProvider',
function($routeProvider) {
$routeProvider.
when('/:thingId', {
templateUrl: 'partials/phone-detail.html'
}).
otherwise({
templateUrl: 'partials/phone-list.html'
});
}]);
//server.js
var express = require('express');
var app = express();
var mysql = require('mysql');
var port = process.env.PORT || 8887;
var db = require('./config/db');
var connection = mysql.createConnection(db);
connection.connect();
app.configure(function()
{
app.use(express.static(__dirname + '/public'));
app.use(express.logger('dev'));
app.use(express.bodyParser());
});
require('./app/router')(app, connection);
app.listen(port);
exports = module.exports = app;
//router.js
module.exports = function(app, conn)
{
app.get('*', function(req, res){
var url = req.originalUrl;
if(url.match(/^\/thing\/.+/))
{
var query_thing = url.replace(/%20/g, ' ');
query_thing = query_thing.replace(/\/thing\//, '');
require('./search')(query_thing, res, conn);
}
else
{
require('./populate')(res, conn);
}
});
};
//populate.js
module.exports = function(res, connection)
{
function getRandIds(rep, max)
{
var ids = [];
//create a list of rep-many random integers, which may have repetitions
for (var i = 0; i < rep; i++)
{
ids.push(Math.floor(Math.random()*100) % max);
}
function numercalSort(a,b)
{
return a-b;
}
//sort() without the callback sorts alphabetically
ids.sort(numercalSort);
console.log(ids);
var notUnique = false;
//check that each id is unique so that the exact number of ids will be queried
for(var i = 0; i < ids.length; i++)
{
if(i+1 < ids.length && ids[i] == ids[i+1])
{
notUnique = true;
}
}
//recurse if the values are not all unique
if(notUnique)
{
ids = getRandIds(rep, max);
}
return ids;
}
//creates a query that searches for random ids
function queryRand(rep, max)
{
var sql = "select m.name, m.imageUrl, v.vid, v.embed from things as m, videos as v where m.id=v.id and (";
var ids = getRandIds(rep, max);
for(var i = 0; i < ids.length; i++)
{
sql += " m.id like "+ids[i];
if(i < ids.length - 1)
{
sql += " or";
}
else
{
sql += ");";
}
}
var sql = "select m.name, m.imageUrl, v.vid, v.embed from things as m, videos as v where m.id=v.id";
return sql;
}
//handles the output
function handleOut(err, result, fields)
{
if(err) throw err;
console.log('rand results: ',result);
res.json(result);
}
var repetitions = 10; //number of things to display
var totalCount = 372; // total number of things in the database
var sql = queryRand(repetitions, totalCount);
connection.query(sql, handleOut);
};
So after a long while, I finally realized that the issue was that I only had one controller that held the functionality for all my controllers. That was only loading once. Because it only loaded once, the $http.get('/things') call was only being made that once when the controller initially loaded. To resolve this, I separated out my controllers. I made one specifically for my home page, and made a separate partial for it and placed the controller specifically in that partial, so it loads every time the partial loads.
This also required updating the index.html and app.js, appropriately.
//mainController.js
angular.module('prjController', [])
.controller('mainController', ['$scope', '$http', '$sce',
function($scope, $http, $sce)
{
$http.get('/things')
.success(function(data)
{
$scope.things = data;
$scope.maxThings = $scope.things.length;
console.log(data);
})
.error(function(data)
{
console.log('Error: ' + data);
});
}]);
<!-- main.html partial -->
<div class="container-fluid" ng-controller="mainController">
<!--Body content-->
...
</div>

Categories

Resources