I'm trying to figure out why the post functions at the end of the following code do not have access to the userID variable (I'm assuming it's a scope issue as logging userId immediately before the functions returns the correct value).
$.get("/set_languages_user", function(res) {
console.log(res)
if ( res.length === 0 ) {
var getUserInfo = $.get('/set_user', function(res){
var langConfirmSource = $('#language-confirmation-template').html();
var langConfirmCompiled = Handlebars.compile(langConfirmSource);
var langConfirmTemplate = langConfirmCompiled(res)
$('body').append(langConfirmTemplate)
$('html').toggleClass('disable_scrolling')
var userId = res.id
var native_language = res.native_language
var learning_language = res.learning_language
$(document).on('submit', '#language_confirmation', function(e){
e.preventDefault()
// prevent user from continuing if they haven't checked that they agree to the term's of use
if ( $('#touCheck').is(':checked')) {
console.log('checked!!!')
// this function finds the ID of the User's defined languages
var getUserInfo = $.get('/languages.json', function(lang){
// Find the ID of the languages the User is supporting in order to submit to languages_users db
for (i = 0; i < lang.length; i++) {
if (lang[i].language === native_language) {
var confirmedUserNativeInt = lang[i].id
}
}
for (i = 0; i < lang.length; i++) {
if (lang[i].language === learning_language) {
var confirmedUserLearningInt = lang[i].id
}
}
console.log(confirmedUserNativeInt)
console.log(confirmedUserLearningInt)
console.log(userId)
// creates a new instance in languages_user for the learningLanguage (level 1)
$.post( "/languages_users", { languages_user:{ language_id: confirmedUserLearningInt, user_id: userId, level: 1 }})
// creates a new instance in languages_user for the nativelanguage (level 5)
$.post( "/languages_users", { languages_user:{ language_id: confirmedUserNativeInt, user_id: userId, level: 5 } })
$('.signon_language_confirmation').remove()
$('html').toggleClass('disable_scrolling')
});
} else {
console.log('not checked!!!')
$('.wrapper_tou_signup').append('<p class="message_form_error">You must agree to Lexody\'s Terms of Use to continue.</p>')
}
})
});
}
})
Here is the handlebars template that is being rendered:
<script id="language-confirmation-template" type="text/x-handlebars-template">
<div class="signon_language_confirmation">
<p class="title_langconf">Welcome to</p>
<img src="">
<div class="wrapper_form_dark language_confirmation_form wrapper_form_sign_on">
<form id="language_confirmation">
<div class="form_section">
<div class="wrapper_input col_16_of_16">
<p>I speak {{native_language}} <svg class="icon_standard"><use xlink:href="#{{native_language}}"/></svg></p>
<p>I am learning {{learning_language}} <svg class="icon_standard"><use xlink:href="#{{learning_language}}"/></svg></p>
<div class="wrapper_tou_signup">
<p><input type="checkbox" name="tou" value="agree" id="touCheck"> I agree to Lexody's terms of use.</p>
</div>
<div class="submit_cancel">
<input type="submit" value="Submit" class="btn_primary submit">
</div>
</div>
</div>
</form>
</div>
</div>
When I submit I'm getting "Uncaught ReferenceError: userId is not defined(…)". How do I make that variable accessible to those functions and why is that variable not accessible but the others ('confirmedUserLearningInt' and 'confirmedUserNativeInt') are?
Thanks in advance.
you have not declared the var's somewhere where the post method can reach, as you can see in your code the vars are inside a if statement which is inside a for loop, you should declare the var before the for loop like this:
$.get("/set_languages_user", function(res) {
console.log(res)
if ( res.length === 0 ) {
var getUserInfo = $.get('/set_user', function(res){
var langConfirmSource = $('#language-confirmation-template').html();
var langConfirmCompiled = Handlebars.compile(langConfirmSource);
var langConfirmTemplate = langConfirmCompiled(res)
$('body').append(langConfirmTemplate)
$('html').toggleClass('disable_scrolling')
var userId = res.id
var native_language = res.native_language
var learning_language = res.learning_language
$(document).on('submit', '#language_confirmation', function(e){
e.preventDefault()
// prevent user from continuing if they haven't checked that they agree to the term's of use
if ( $('#touCheck').is(':checked')) {
console.log('checked!!!')
// this function finds the ID of the User's defined languages
var getUserInfo = $.get('/languages.json', function(lang){
// Find the ID of the languages the User is supporting in order to submit to languages_users db
var confirmedUserNativeInt; //<<<<<<<<<<<<<<
for (i = 0; i < lang.length; i++) {
if (lang[i].language === native_language) {
confirmedUserNativeInt = lang[i].id
}
}
var confirmedUserLearningInt;//<<<<<<<<<<<<<<<<
for (i = 0; i < lang.length; i++) {
if (lang[i].language === learning_language) {
confirmedUserLearningInt = lang[i].id
}
}
console.log(confirmedUserNativeInt)
console.log(confirmedUserLearningInt)
console.log(userId)
// creates a new instance in languages_user for the learningLanguage (level 1)
$.post( "/languages_users", { languages_user:{ language_id: confirmedUserLearningInt, user_id: userId, level: 1 }})
// creates a new instance in languages_user for the nativelanguage (level 5)
$.post( "/languages_users", { languages_user:{ language_id: confirmedUserNativeInt, user_id: userId, level: 5 } })
$('.signon_language_confirmation').remove()
$('html').toggleClass('disable_scrolling')
});
} else {
console.log('not checked!!!')
$('.wrapper_tou_signup').append('<p class="message_form_error">You must agree to Lexody\'s Terms of Use to continue.</p>')
}
})
});
}
})
Related
I'm trying my first weather api APP. Here I'm trying to achive that if the city weather is already displayed , It should give the message "You already know the weather" . and should not repeat the weather
Here is my code. Anyone Please look at my code ...
What is the mistake I have been made.
<div class="main">
<div class="container">
<div class="search_por">
<h2>Weather </h2>
<div class="validate_msg color_white"></div>
<form>
<label for=""></label>
<input type="search" class="input_text" value="">
<button type="submit" id="sub_button" class="srh_button">Search</button>
</form>
<!-- <canvas id="icon1" width="150" height="75"></canvas> -->
<div class="dat_weather">
<ul id="list_it">
</ul>
</div>
</div>
</div>
</div>
var get_text=document.querySelector("form");
get_text.addEventListener("submit",e=>{
e.preventDefault();
var input_val=document.querySelector('input').value;
const apiKey="bc4c7e7826d2178054ee88fe00737da0";
const url=`https://api.openweathermap.org/data/2.5/weather?q=${input_val}&appid=${apiKey}&units=metric`;
fetch(url,{method:'GET'})
.then(response=>response.json())
.then(data=>{console.log(data)
const{main,sys,weather,wind}=data;
//icons-end
var error_ms=document.getElementsByClassName("validate_msg")[0];
var iconcode = weather[0].icon;
console.log(iconcode);
var li=document.createElement("Li");
var weatherinfo=`<div class="nameci font_40" data-name="${data.name},${sys.country}"><span>${data.name}</span><sup>${sys.country}</sup></div>
<div class="temp_ic">
<img class="weat_icon" src="http://openweathermap.org/img/w/${iconcode}.png">
<div class="deg">${Math.floor( main.temp )}<sup>o</sup></div>
</div>
<div class="clear">
<div>${weather[0].description}</div>
</div>
`;
li.innerHTML=weatherinfo;
var ulid=document.getElementById("list_it");
ulid.appendChild(li);
var city_name=data.name;
console.log(skycons);
var listitems=document.querySelectorAll('#list_it');
const listArray=Array.from(listitems);
if(listArray.length>0)
{
var filtered_array=listArray.filter(el=>{
let content="";
if(input_val.includes(','))
{
if(input_val.split(',')[1].length>2)
{
alert("hving 2 commos");
inputval=input_val.split(',')[0];
content=el.querySelector(".nameci span").textContent.toLowerCase();
//content=el.querySelector(".nameci").innerHTML.toLowerCase();
//content=inputval.toLowerCase();
}
else
{
content=el.querySelector(".nameci").dataset.name.toLowerCase();
}
alert(filtered_array);
}
else
{
content=el.querySelector(".nameci span").textContent.toLowerCase();
}
console.log(inputval.toLowerCase());
return inputval.toLowerCase();
});
if(filtered_array.length>0)
{
console.log(filtered_array.length);
error_ms.innerHTML="You Already know the weather of this country....";
get_text.reset();
return;
}
}
})
.catch((error)=>{
error_ms.innerHTML="Please Enter a valid city Name";
});
var error_ms=document.getElementsByClassName("validate_msg")[0];
error_ms.innerHTML="";
//var get_text=document.querySelector("form");
get_text.reset();
});
My full code is here:
https://codepen.io/pavisaran/pen/wvJaqBg
Let's try keeping track of a list of displayed locations outside of the callback:
var get_text = document.querySelector("form");
// Keep Track Of Displayed Cities Here Instead
let displayed = [];
get_text.addEventListener("submit", e => {
e.preventDefault();
var input_val = document.querySelector('input').value;
const apiKey = "bc4c7e7826d2178054ee88fe00737da0";
const url = `https://api.openweathermap.org/data/2.5/weather?q=${input_val}&appid=${apiKey}&units=metric`;
fetch(url, {method: 'GET'})
.then(response => response.json())
.then(data => {
var error_ms = document.getElementsByClassName("validate_msg")[0];
const {main, sys, weather, wind, name} = data;
if (displayed.length > 0) {
// Filter Displayed Based on Current vs name from data (response)
const filtered_array = displayed.filter(el => el === name);
if (filtered_array.length > 0) {
error_ms.innerHTML = "You Already know the weather of this country....";
get_text.reset();
return Promise.resolve();
}
}
// Add City To Array of Displayed Cities
displayed.push(name);
// Do Rest of Code to Add New City
var iconcode = weather[0].icon;
var li = document.createElement("Li");
var weatherinfo = `<div class="nameci font_40" data-name="${data.name},${sys.country}"><span>${data.name}</span><sup>${sys.country}</sup></div>
<div class="temp_ic">
<img class="weat_icon" src="http://openweathermap.org/img/w/${iconcode}.png">
<div class="deg">${Math.floor(main.temp)}<sup>o</sup></div>
</div>
<div class="clear">
<div>${weather[0].description}</div>
</div>
`;
li.innerHTML = weatherinfo;
var ulid = document.getElementById("list_it");
ulid.appendChild(li);
})
.catch((error) => {
error_ms.innerHTML = "Please Enter a valid city Name";
});
var error_ms = document.getElementsByClassName("validate_msg")[0];
error_ms.innerHTML = "";
get_text.reset();
});
You have to just check for the value which is coming from api whether it's present on your list or not. you can try this.
li.innerHTML=weatherinfo;
var ulid=document.getElementById("list_it");
var isPresent = false;
var items = ulid.getElementsByTagName("li");
for (var i = 0; i < items.length; i++){
if(items[i].innerHTML == li.innerHTML){
alert("you already know the weather")
isPresent = true;
}
}
if(!isPresent){
ulid.appendChild(li);
}
I am fairly new to AngularJS and I have been reading some answers here but nothing worked out. I have a json file from a controller that I display in a select. I want to set the selected value based on the text value.This is what I have so far.
HTML:
<div ng-app="userModule" ng-controller="userCtrl">
<div class="row">
<div class="col-md-6">
<label>User Name:</label> <br />
<select ng-model="users.selectedUser" class="form-control" ng-options="item.UserName as item.UserName for item in users.availableOptions"></select>
</div>
Controller:
<script>
var _$http;
var _$scope;
var oldUser = #Html.Raw(Json.Serialize(ViewData["UserName"]));
var oldRole = #Html.Raw(Json.Serialize(ViewData["RoleName"]));
angular.module('userModule', [])
.controller('userCtrl', xConstructor);
function xConstructor($scope, $http) {
_$http = $http;
_$scope = $scope;
$http.get("/RoleManagement/GetUserData").then(xReceive);
$http.get("/RoleManagement/GetRoleData").then(roleReceive);
_$scope.submit = function () {
//alert("Here:" + _$scope.selectedUser);
$http.get("/RoleManagement/PutUserRoleData?UserId=" + _$scope.selectedUser.UserId + "&RoleId=" + _$scope.selectedRole.RoleId).then(writeSuccess);
}
}
function xReceive(userObject) {
_$scope.users = {
availableOptions: userObject.data,
**selectedUser: { UserId: oldId, UserName: oldUser } //What to put here?**
};
alert(JSON.stringify(JSON.stringify(_$scope.users.selectedUser));
}
</script>
Or any other suggestions on how to do this?
The problem is you are not mapping the model to any element in the array you have.
Assuming you have the id of the user you want to select this is what you do:
function xReceive(userObject) {
_$scope.users = {
availableOptions: userObject.data,
selectedUser: null
};
let selectedUser;
for (let i = 0; i < userObject.data.length; i++) {
if (userObject.data[i].id === oldId) {
selectedUser = userObject.data[i];
break;
}
}
if (selectedUser) {
_$scope.users.selectedUser = selectedUser;
}
alert(JSON.stringify(JSON.stringify(_$scope.users.selectedUser));
}
Also note, you can do this to just select the first one:
_$scope.users.selectedUser = _$scope.users.availableOptions[0];
I am new to angular js. I have a link http://www.bursamalaysia.com/searchbox_data.json that I want to get a list of name and id.
I able to get the list from a link in json but I need to filter unwanted items in the list. If the id is more than 4 digits, then remove full_name,name, short_name and id. example: if id:123456 , it need to be filter out, together with name,short name.
app.js
abc: {
name: "Momo",
value: "kls",
long: "KLSE",
searchRef: KLSE_SEARCH_REF,
searchRefURL: "http://www.bursamalaysia.com/searchbox_data.json",
},
details.js
$ionicLoading.show();
if ($scope.currentMarket == "abc"){
$webServicesFactory.getNotParsed($marketProvider[$scope.currentMarket].searchRefURL).then(function success(response){
response = JSON.parse(response);
for (var i = 0; i < response[0].length; i++){
$scope.searchRef.push({
name: response[0][i].name || response[0][i].full_name,
symbol: response[0][i].short_name,
code: response[0][i].id,
market: $marketProvider[$scope.currentMarket].long
});
}
console.info($scope.searchRef);
$ionicLoading.hide();
});
}
html
<div class="list">
<div class="item" ng-repeat="item in searchItems" ng-click="openDetail(item)">
<p>{{item.symbol}} - {{item.name}}</p>
<p>{{currentMarket | uppercase}}</p>
</div>
</div>
You could go with Array.prototype.filter and Array.prototype.map, which is quite elegant.
$ionicLoading.show();
if($scope.currentMarket == "abc") {
$webServicesFactory.getNotParsed($marketProvider[$scope.currentMarket].searchRefURL).then(
function success(response) {
$scope.searchRef = JSON.parse(response)[0].filter(function(itm) {
// whatever you want to filter should pass this condition
return itm.id.toString().length <= 3;
}).map(function(itm) {
// for each item, transform to this
return {
name: itm.name || itm.full_name,
symbol: itm.short_name,
code: itm.id,
market: $marketProvider[$scope.currentMarket].long
};
});
$ionicLoading.hide();
}
);
}
Make sure to handle any errors and to make your code defensive.
if you need filter more than 4 digit id values , then you can restrict with simple condition if(response[0][i].id <= 999)
example below:
for(var i=0; i<response[0].length; i+=1){
if(response[0][i].id.toString().length <= 3 ) {
$scope.searchRef.push(
{
name: response[0][i].name || response[0][i].full_name,
symbol: response[0][i].short_name,
code: response[0][i].id,
market: $marketProvider[$scope.currentMarket].long
}
);
}
}
I've seen a few posts asking the same question but I can't make it work. I'm quite new to angular so I would need help.
I'm trying to insert a new income with tags.
I get thoses tags from a service and display them like this :
<label ng-repeat="tag in tags">
<input type="checkbox" ng-model="tags_chosen" name="tags_chosen[tag]" ng-true-value="<%tag.id%>"/> <%tag.name%>
</label>
When I try to get back the checkbox values in angular, it doesn't work :
this.addIncome = function($scope) {
var data = {
'project_id':$scope.project_id,
'amount':$scope.amount,
'payment_date':$scope.payment_date,
'tags':$scope.tag_chosen,
'description':$scope.description,
'type':$scope.type
};
return $http.post(URL.BASE_API + 'income/store',data).
success(function(response) {
ServicesStatus.return = response;
}).error(function(response) {
console.log('Service error');
});
};
How could I do that ?
Thanks !
try this:
$scope.tag_chosen =[];
$scope.toggleSelection = function ( deviceId, $event ) {
var checkbox = $event.target;
var action=(checkbox.checked ? 'add':'remove');
var idx = $scope.tag_chosen.indexOf( deviceId );
// is currently selected
if (action=='remove' && idx != -1 ) {
$scope.tag_chosen .splice( idx, 1 );
}
// is newly selected
if (action=='add' && idx == -1 ) {
$scope.tag_chosen.push( deviceId );
}
and in html >>
ng-click="toggleSelection(yourcjeckbox value,$event)"
I followed information on this answer
But it doesn't work in my situation.
Chrome Inspector console says "ReferenceError: dataResponse is not defined"
maybe that is the problem?
I am trying to GET this JSON from url:
[{"app_id":1,"app_name":"oh yeeah","app_description":"desc","app_price":111,"is_activated":false,"video":"videolink"},{"app_id":2,"app_name":"oh yeaaaeah","app_description":"ewaewq","app_price":222,"is_activated":false,"video":"fuck off"},{"app_id":3,"app_name":"oh yeaaaeah","app_description":"ewaewq","app_price":333,"is_activated":false,"video":"fuck off"}]
This is my javascript code
var appstore = angular.module('appstore', []);
appstore.service('dataService', function($http) {
delete $http.defaults.headers.common['X-Requested-With'];
this.getData = function(callbackFunc) {
$http({
method: 'GET',
url: '/administrator/components/com_apps/loadAppsJson.php'
}).success(function(data){
callbackFunc(data);
}).error(function(){
alert("error");
});
}
});
appstore.controller('app_Ctrl', function($scope, dataService) {
$scope.apps = [
{app_id:1, app_name:'oh yeah', app_description:'$app_description', app_price:111, is_activated:false, video:'$videolink'},
{app_id:2, app_name:'oh yeah', app_description:'$app_description', app_price:111, is_activated:false, video:'$videolink'},
{app_id:3, app_name:'oh yeah', app_description:'$app_description', app_price:111, is_activated:false, video:'$videolink'},
];
//$scope.apps = null;
dataService.getData(function(dataResponse) {
$scope.apps = dataResponse;
alert(dataResponse);
});
console.log(dataResponse);
console.log($scope.apps);
//get images thumbs
for(app = 0; app <= $scope.apps.length-1; app++) {
$scope.apps[app].thumb = ("000" + $scope.apps[app].app_id).slice(-3);
}
//separate apps to columns
var columns = [];
for (var i = 0; i < $scope.apps.length; i++ ) {
if (i % 3 == 0) columns.push([]);
columns[columns.length-1].push($scope.apps[i]);
}
$scope.columns = columns;
});
My HTML view
<div ng-controller="app_Ctrl">
<div class="row"></div>
<div class="row">
<div class="row" ng-repeat="apps in columns">
<div id="app_id_{{ app.app_id }}" class="col-lg-4" ng-repeat="app in apps | filter:search">
<div class="thumbnail" ng-class="app.is_activated ? 'activated' : ''">
<!-- -->
<img ng-src="/images/apps/app_images/{{ app.thumb }}_thumb.jpg" alt="{{ app.app_name }}" title="{{ app.app_name }}">
<div class="caption">
<h3>{{ app.app_name }}</h3>
<p class="app_price">{{ app.app_price }} €</p>
<div style="clear:both;"></div>
<p class="app_card_description">{{ app.app_description | limitTo:100 }}...</p>
Info
Video <span class="glyphicon glyphicon-facetime-video"></span>
{{ app.is_activated ? 'Aktivované' : 'Aktivovať' }}
</div>
</div>
</div>
</div>
To elaborate on what #Mritunjay said in the comments; review this code with comments:
dataService.getData(
// this is your callback function which has an argument for dataResponse
// the dataResponse variable will only be defined within the Call back function
function(dataResponse) {
$scope.apps = dataResponse;
alert(dataResponse);
// The Curly Brackets that follow mark the end of the callback handler method
});
// This log statement is not in the callback handler and there is no defined dataResponse variable which is probably why you got an error in the console
console.log(dataResponse);
You can fix this by moving the dataResponse log into the callback method, like this:
dataService.getData(function(dataResponse) {
$scope.apps = dataResponse;
alert(dataResponse);
console.log(dataResponse);
});
There appear to be other problems with your code, in that you are trying to access $scope.apps before the data is returned; which will hinder your processing. Easiest approach would be to move that processing into the result handler:
// define $scope.columns outside of the result handler
$scope.columns = [];
// call to method in service
dataService.getData(function(dataResponse) {
$scope.apps = dataResponse;
alert(dataResponse);
console.log(dataResponse);
// inside the result handler; you run this code after $scope.apps is defined:
for(app = 0; app <= $scope.apps.length-1; app++) {
$scope.apps[app].thumb = ("000" + $scope.apps[app].app_id).slice(-3);
}
//separate apps to columns
var columns = [];
for (var i = 0; i < $scope.apps.length; i++ ) {
if (i % 3 == 0) columns.push([]);
columns[columns.length-1].push($scope.apps[i]);
}
$scope.columns = columns;
});
That's what promises and asynchronous calls are all about.
console.log(dataResponse);
console.log($scope.apps);
The first one won't work because dataResource is a private variable and not part of the same scope you're trying to print.
The second one won't work either because that get's populated at future time (after X seconds), after the $http request is finished so it will only be availableat that point.
One way to do something after the object is populated is to use
$scope.$watch("apps", function (){
// do stuff
});