TypeScript - zachowanie bloku if-else.

0

Drodzy Forumowicze,
mam taki kawałek kodu napisany w TypeScripcie:

$.get(url).then((result) => {
            debugger;
            var czySpisElektroniczny = result as boolean;
            if (czySpisElektroniczny) {
                s.GetTab(tabIndex).SetVisible(true);
            } else {
                debugger;
                s.GetTab(tabIndex).SetVisible(false);
            }
        });

W takim przypadku program zawsze wchodzi w if(czySpisElektroniczny) i to niezależnie od tego czy result jest true czy false. Kiedy jednak poprawię warunek na taki:

if (czySpisElektroniczny == true)

to program zachowuje się już tak jak się spodziewałem, czyli w przypadku result = false wchodzi w blok else. ReSharper jednak się wymądrza i podkreśla mi na niebiesko chcąc zmienić tę linijkę na wersję pierwszą, która nie zachowuje się tak jak powinna. Mam świadomość niuansów w TypeScripcie jednak zupełnie nie rozumiem tego zachowania.
Będę wdzięczny za wyjaśnienie mi tego jak 5-latkowi :D Wszystkie wskazówki będą dla mnie istotne.

Pozdrawiam,
DB.

0

Nie, dla '===' wchodzi w else w przypadku gdy result = true. Teraz jestem już zupełnie skołowany.

2

ten result na pewno jest true a nie jest jakimś "true" czy czymś innym? Generalnie jeśli przy '===' nie wchodzi to znaczy, że twój obiekt nie jest boolem. Generalnie co chcesz uzyskać bo może nie musisz wcale go na wartość logiczną rzutować :).

EDIT: Wgl co ty chcesz na tego boola castowac :D?

0

Jak zatrzymuję na debuggerze to Firefox pokazuje True albo False.
Potrzebuję wyciągnąć boola z kontrolera MVC i getem uderzam do akcji, która zwraca true/false. Potem na podstawie boola wywołuję jedną z dwóch możliwości. Jestem w trakcie nauki TypeScripta i nie wiem jeszcze jak to zrobić w sposób całkowicie kanoniczny :)

result jest domyślnie jako any.

No tak, mogłem wcześniej na to wpaść... Result jest stringiem :D
screenshot-20191019183635.png
No to kolejne pytanie - czemu result jest stringiem skoro akcja w kontrolerze zwraca mi boola?

1

A jednak komentarz xD byl wartosciowy. A go usunąłem. Well jest XXI wiek polecam zrezygnować z jquery na rzecz jakiegoś Angulara/Reacta/Vue ale do rzeczy. Pokaż kod controllera z MVC. To może uda mi się coś wyczarować ;). Anywya zapytalbym predzej czemu result jest "True" a nie true

0

Nie zawsze mamy wpływ na wybór technologii :P Kod akcji z kontrolera to nic nadzwyczajnego, ot tyle:

public bool CzySpisElektroniczny()
{
            var rodzajSpisu = TempData["RodzajSpisu"] as string;
            return rodzajSpisu == RodzajSpisu.Elektroniczny.ToString();
}       

Ewidentnie zwraca boola.

1

To się kompiluje? :0 przecież to zwraca stringa. Popatrz na ostatni frargment funkcji "ToString()". Weź wyrzuć te ToString(). Bo raz, że to komplikuje sprawę bo ToString() na bool daje duże litery a nie małe

0
Akihito napisał(a):

To się kompiluje? :0 przecież to zwraca stringa. Popatrz na ostatni frargment funkcji "ToString()". Weź wyrzuć te ToString(). Bo raz, że to komplikuje sprawę bo ToString() na bool daje duże litery a nie małe

Zobacz na linijkę z returnem. Jest porównanie dwóch stringów. To nie zwraca stringa tylko boola, jedynie zapis jest skrócony. Z C# jestem zdecydowanie mocniejszy niż z TypeScript i akurat tego jestem pewien :P Nie mogę skasować ToString(), bo RodzajSpisu to enum.

dawid75_75 napisał(a):
Akihito napisał(a):

To się kompiluje? :0 przecież to zwraca stringa. Popatrz na ostatni frargment funkcji "ToString()". Weź wyrzuć te ToString(). Bo raz, że to komplikuje sprawę bo ToString() na bool daje duże litery a nie małe

Zobacz na linijkę z returnem. Jest porównanie dwóch stringów. To nie zwraca stringa tylko boola, jedynie zapis jest skrócony. Z C# jestem zdecydowanie mocniejszy niż z TypeScript i akurat tego jestem pewien :P Nie mogę skasować ToString(), bo RodzajSpisu to enum.

I owszem, ToString na boolu robi wielką literę na początku, ale w tym przypadku nie ma to znaczenia, bo nie robię ToString na boolu tylko na enumie. Porównanie jest pomiędzy dwoma stringami.

1

dobra jestem ślepy nie zauważyłem ==. W sumie nigdy nie zwracałem pojedynczej zmiennej zawsze to był to obiekt. Wydaje mi się, że GET nie może zwrócić sam w sobie boola możesz zwrócić obiekt który boola zawiera. Tak więc zwraca ci stringa co by tłumaczyło czemu jest True i False zamist true i false. Polecam chyba się nie przejmować i poprawić kod w js:

$.get(url).then((result) => {
            debugger;
            var czySpisElektroniczny = eval(result.toLowerCase());
            if (czySpisElektroniczny) {
                s.GetTab(tabIndex).SetVisible(true);
            } else {
                debugger;
                s.GetTab(tabIndex).SetVisible(false);
            }
        });
0

Ok, rozumiem. Mogę tak poprawić. A gdybym zwrócił jsona? Jak czytam teraz z trochę większą uwagą to chyba taki numer można zrobić: https://www.w3schools.com/jquery/ajax_get.asp

1

@dawid75_75: Jeśli chcesz JSONA to potrzebujesz obiekt możesz albo zwrócić ActionResult albo pobawić się w aspekty spróbujmy na przykładzie z neta:

public ActionResult CzySpisElektroniczny()
{
            var rodzajSpisu = TempData["RodzajSpisu"] as string;
            var data = new { CzySpisElektroniczny = rodzajSpisu == RodzajSpisu.Elektroniczny.ToString() }
            return Json(data)
}       
$.get(url).then((result) => {
            debugger;
            var czySpisElektroniczny = result.CzySpisElektroniczny;
            if (czySpisElektroniczny) {
                s.GetTab(tabIndex).SetVisible(true);
            } else {
                debugger;
                s.GetTab(tabIndex).SetVisible(false);
            }
        });

jeślli nigdize sie nie machnalem to powinno zadziałać :)

1

No to kolejne pytanie - czemu result jest stringiem skoro akcja w kontrolerze zwraca mi boola?

Bo próbujesz surowy wynik z endpointu C# użyć bezpośrednio w JS. W js nie ma czegoś takiego jak True / False, więc będzie to traktowane jako string "True"/"Flase" (oba są truthy).

0

Równolegle próbowałem u siebie :D Mam lekko inaczej, ale rezultat prawidłowy. Akcja:

public JsonResult CzySpisElektroniczny()
{
            var rodzajSpisu = TempData["RodzajSpisu"] as string;
            return Json(new {czySpisElektroniczny = rodzajSpisu == RodzajSpisu.Elektroniczny.ToString()}, JsonRequestBehavior.AllowGet);
}

Niedokończony kod w TS:

$.get(url, (data, textStatus, jqXHR) => 
{
     debugger; 
}, "json");

Efekt finalny widoczny w konsoli:
screenshot-20191019192132.png

Wyjaśniłbyś mi jeszcze działanie then? W dokumentacji callback po getcie można ustawić w samym wywołaniu geta. Czy chodzi o to, że then odpala się zawsze, a callback w getcie tylko jak jest status = success?

1

Czy chodzi o to, że then odpala się zawsze, a callback w getcie tylko jak jest status = success?

Nie patrząc w dokumentację jQ - niemal na 100% callback i then robią dokładnie to samo w tym przypadku. Różnica jest taka, że używając promise nie musisz obsługiwać wyniku od razu, możesz sobie wynik $.get('//some-url') przekazać do innej funkcji/zwrócić i obsłużyć go w innym mijescu (albo ubsłużyć część ii then zwróci kolejnego promisa, którego możesz dalej obsługiwać).

0

Dzięki za te wszystkie uwagi, sporo się dowiedziałem. Powiedzcie mi proszę jeszcze jedną rzecz. Składnia geta jest dokładnie taka:

$.get(URL,data,function(data,status,xhr),dataType)

O ile wprost jest napisane, że dataType jest opcjonalny to już function(data, status, xhr) wygląda jakby miał stałą sygnaturę. Dlaczego więc mogę zrobić tak:

$.get(url, (data) => {
            debugger;
        }, "json");

i nie ma żadnego błędu? To jest oczywiście dla mnie wygodne, bo wystarczy mi data jednak nie rozumiem dlaczego skrócenie sygnatury tej funkcji jest traktowane poprawnie.

2

nie rozumiem dlaczego skrócenie sygnatury tej funkcji jest traktowane poprawnie

Twórcy TS uznali, że to będzie przydatny i wygodny ficzer - https://fettblog.eu/typescript-substitutability/

1 użytkowników online, w tym zalogowanych: 0, gości: 1