Meteor templates: If statement is no reactive - meteor-blaze

I'm having troubles with Blaze (Meteor 1.2.0.2)
If are evaluated in templates, but when their are not true anymore, the content is still printed.
Template.registerHelper("equals", function (a, b) {
return (a == b);
});
Template.login.helpers({
'loadingLogoStatus': function(){
lg(Session.get('logoDownloadStatus'));
return Session.get('logoDownloadStatus');
},
'logoURI': function(){
return Session.get(Session.get('logoURI')) || '';
}
});
{{#if loadingLogoStatus equals 'WAIT_DOWNLOAD'}}
Logo is loading...
{{/if}}
{{#if loadingLogoStatus equals 'ERR_DOWNLOAD'}}
Logo loading error
{{/if}}
The issue is in fact that as long as loadingLogoStatus == 'WAIT_DOWNLOAD', Logo is loading... is printed.
However when loadingLogoStatus = 'ERR_DOWNLOADED**, the previous string remains there and it's followed by Logo loading error.
Same situation if I try with a if/else construct.
I checked whether it was helper's issue and it wasn't since on Session variable change, the new value is printed to log.

Try a === b
You need 3 equal signs In JavaScript to evaluate one value to another.

I found what the issue was.
I was using equals in the wrong position.
Right one:
{{#if equals loadingLogoStatus 'WAIT_DOWNLOAD'}}
Logo is loading...
{{/if}}
{{#if equals loadingLogoStatus 'ERR_DOWNLOAD'}}
Logo loading error
{{/if}}

Related

Ternary operator in Typescript based Reactjs does not work as I expected

I am newbie in TypeScript+ReactJS
In my code Ternary operator does not work as I expect.
This is my code:
import React, { SyntheticEvent,useRef,useState } from "react";
import Result from './Result';
//main application
const App:React.FC=()=>{
const [searchResult,setSearchResultState]=useState<Array<Object>>([]);
const setSearchResultFunc = (value:Array<Object>)=>{
setSearchResultState(value);
}
return (
<section id="App">
<SearchPanel setResult={setSearchResultFunc}/>
{
(searchResult===[])
?""
:<Result result={searchResult}/>}
<footer className={searchResult===[]?"absolute":""}>
<p>All data are received using Google Place API. {"result: " +searchResult}
<br/>
This website is not actual working website and is made just for educational purpose.
</p>
</footer>
</section>
)
}
export default App;
interface searchProps{
setResult:(value: Array<Object>) => void
}
const SearchPanel=({setResult}:searchProps)=>{
const searchElementRef = useRef(null as any);
const search =(e:SyntheticEvent)=>{
const searchValue = searchElementRef.current.value;
if(typeof searchValue!=="string"){
alert("only text allowed");
}else{
//validate user search input
regexValidate(searchValue)
?alert("No special characters are allowed")
//send request to server if no special character is found
:fetch("//localhost:3000/city?name="+searchValue,{
method:'GET',
credentials:'include',
headers:{
'Accept':'application/json',
'Content-Type':'application/json'
}
}).then((data:any)=>{
return data.json();
}).then(data=>{
setResult(Object.entries(data));
})
}
e.preventDefault();
}
const regexValidate = (value:string)=>{
const specialChars = /[`!##$%^&*()_+\-=\[\]{};':"\\|,.<>\/?~]/;
return specialChars.test(value);
}
return(
<section className="text-center absoluteCenter">
<h1 className="text-white text-lg uppercase mb-5">Wanna travel somewhere?</h1>
<form action="/" method="GET" onSubmit={e=>search(e)}>
<input type="text" placeholder="SEARCH FOR CITY ex:London" ref={searchElementRef}/>
</form>
</section>
)
}
So, what I expect is, when application starts, the App component will have an empty Array state which is called searchResultFunc. And when user performs a search, it will update the state by calling function setResultState. The function will have data that search has returned and will alter previous state data to the new data.
According to this ternary operator,
{
(searchResult===[])
?""
:<Result result={searchResult}/>
}
I thought the page should not have Result component from beginning, but when I render the page for first time,
I already see Result in HTML inspector which means ternary operator does not work as I expected.
To check the value of state when the page renders for first time, I made such code
<p>All data are received using Google Place API. {"result: " +searchResult}
<br/>
This website is not actual working website and is made just for educational purpose.
</p>
If state searchResult has some data, the webpage should show value of the state. However, the result state is empty.
What did I do wrong?
you need to change searchResult===[] to searchResult.length === 0
When you compare arrays using === you are actually checking whether the two arrays are the same array. It does not check whether the two arrays have the same content.
Here's a short program that illustrates the difference: https://www.typescriptlang.org/play?#code/MYewdgzgLgBAhgLhtATgSzAcwNoF0YC8MeAUKJLAEZKoY75GnnQzA1TpZ6Hwl-MgANgFMAdIJCYAFAHI4BApQD8MgDTwFlAJRlwEIWInS5C4CvXyCwHXyA
You need to check whether array is empty or not. You can do the following.
arr=[]
arr.length === 0? True : False
arr===[] does not work as it checks the array reference whether both the array points toward same memory reference. Hence it will fail everytime even if elements are same in both array unless and until it's same array referenced.

Protractor ng-if condition and element availability

I want to check whether element displayed or not depends upon ng-if condition,
<div id="discount_percent" ng-if="data.isDiscount">
<div id="dis_available"> Discount: {{data.discount}} % </div>
</div>
I want to check if data.isDiscount is true than div "discount_percent" & dis_available should display.
Note: div "discount_percent" and "dis_available" won't be present in DOM if data.isDiscount is false.
I did following way, but I'm not fully satisfied with my solution.
var discountPercentId = element(by.id('discount_percent'));
discountPercentId.isPresent().then(function (present){
if(present){
expect(discountPercentId.evaluate("data.isDiscount")).toBeTruthy();
expect(discountPercentId.element(by.id("dis_available")).isDisplayed()).toBeTruthy();
}
});
Any better approach to do? If condition true than check its availability!!!
try this:
var elem = element(by.css('[ng-if="data.isDiscount"]'));
elem.isPresent().then(function(fnct){
if(fnct){
//do whatever
}
else{
//do something else
}
});
also, I am not sure, but you might want to get the value of data.IsDiscount first. You can get the value of this with the following function:
elem.getAttribute('value').then(function(value) {
//do something with the value
});

value of progressbar doesnt work

theres my progress bar code:
<div class="col-sm-4" ng-repeat="var in payloadNbrMissionParStatut">
<h4 class="no-margin">{{var.number}}</h4>
<progressbar value={{tom}} class="progress-xs no-radius no-margin" type={{gg}} ng-if="var.des=='Clos' ? gg='danger' : var.des=='En cours'? gg='warning' :gg='info' " ></progressbar>
{{var.des}}
</div>
the problem is in the value: when i populate it with static data it works good, but when i populate wit data come from the controller it doesnt work.
var is a reserved JS keyword. As errors inside directive expressions are silent, you aren't seeing any alerts because it's simply being ignored. Change var to something else and it should work.

Angular ng-show is not working as expected

I am using ng-show in below html code:
<span ng-show="show_notif_count=1" class="m-alert" id="notif_count">{{notif_count}}</span>
js code:
$scope.show_notif_count = 0;
$http.get('count/',{headers:{'Content-Type':'application/x-www-form-urlencoded'}})
.success(function(response)
{
console.log($scope.show_notif_count);
if(response>2)
{
$scope.show_notif_count = 1;
console.log(response);
$scope.notif_count = response;
}
});
The problem is ng-show never hides the span and it always keeps on showing. I have tried using "==" instead of "=" and also other values for "show_notif_count" but either it always shows up or always keeps hiding. what could be wrong with above code?
show_notif_count=1 is set value for variable not to compare.
Update:
<span ng-show="show_notif_count=1" class="m-alert" id="notif_count">{{notif_count}}</span>
To:
<span ng-show="show_notif_count === 1" class="m-alert" id="notif_count">{{notif_count}}</span>
Note: It will hide when response <= 2, please check response again.

AngularJs Divs won't toggle using <select>

I have this in my view:
<div>
<select ng-model="chartType" ng-change="AnalyticsChartTypeChanged(chartType)"
ng-init="chartType='Data grid'">
<option value="Data grid">Data grid</option>
<option value="Histogram">Histogram</option>
</select>
{{chartType}}
<br>showAnalyticsDataGrid == {{showAnalyticsDataGrid}}
<br>showAnalyticsHistogram == {{showAnalyticsHistogram}}
<div ng-show="{{showAnalyticsDataGrid}}">
<p>Data grid goes here</p>
</div>
<div ng-show="{{showAnalyticsHistogram}}">
<p>Histogram goes here</p>
</div>
and the ng-chnage funtion is
$scope.AnalyticsChartTypeChanged = function(chartType)
{
switch (chartType)
{
case 'Data grid': $scope.showAnalyticsDataGrid = true;
$scope.showAnalyticsHistogram = false;
console.log('Show analytics data grid');
break;
case 'Histogram': $scope.showAnalyticsDataGrid = false;
$scope.showAnalyticsHistogram = true;
console.log('Show analytics histogram');
break;
}
}
When I alernately select each of the options, the debug text updates correcrly:
Data grid
showAnalyticsDataGrid == true
showAnalyticsHistogram == false
and
Histogram
showAnalyticsDataGrid == false
showAnalyticsHistogram == true
BUT, it constantly shows the Data grid DIV and never the Historgram DIV.
Obviouly I am making an extermely simple mistake, but I just can't see it :-(
With ng-show, you give it an expression and it evaluates it for you. What you're trying to do here is evaluating the expression by using the double curly braces{{}}, which doesn't make sense. If you simply remove those double curly braces and use the ng-show like this:
ng-show="showAnalyticsDataGrid"
it will work just fine.
Also, remember that those 2 variables aren't being initialized so when the view loads there will be no div shown by default, but you can fix that with an ng-init.
Here's a fiddle. http://jsfiddle.net/5DMjt/5248/
You don't use {{}} interpolation in ng-show. Like many other directives it directly evaluates expressions
Change
<div ng-show="{{showAnalyticsHistogram}}">
To
<div ng-show="showAnalyticsHistogram">

Resources