Fehlersuche Flask, mit Vue.js
Ach, was soll ich dazu auch sagen, außer vielen Dank für den Hinweis.
Jetzt funktioniert es :
Ist die Vorgehensweise eigentlich okay so oder gibt es etwas geschickteres?
Danke und Grüße
Dennis
Jetzt funktioniert es :
Code: Alles auswählen
<html>
<head>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
</head>
<body>
<div id="app">
<h2>Gasmischung erstellen</h2>
<li v-for="gas in gases" :key="gas_name">
<select v-model="gas[gas_name]">
<option disabled value="">Bitte auswählen</option>
<option v-for="name in validGases" :key="name">
{{name}} </option>
</select>
<input v-model="gas[percent]">%
</li>
<button @click="add_gas">+</button>
</div>
<script>
const { createApp, ref } = Vue
createApp({
setup() {
const gases = ref([{gas_name: undefined, percent: undefined}])
const gas_name = ref("")
const percent = ref(0)
function add_gas() {
gases.value.push({gas_name: gas_name.value, percent: percent.value})
}
validGases = [
"H2",
"CO2",
"CO"
]
return {
add_gas,
gas_name,
percent,
gases,
validGases
}
}
}).mount('#app')
</script>
</body>
</html>
Danke und Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
Guten Abend zusammen,
habe es geschafft, dass die Seite alle Eingabefelder ink. der Gasmischung in JavaScript validiert. Hat mich nur 5 Nervenzusammenbrüche gekostet und aus den Haaren auf dem Schreibtisch, kann man zumindest einen kleinen Besen machen.
Nun müssen die Daten Richtung Flask-App geschickt werden. In meinem Tutorial wird dafür `axios` importiert. Wenn ich das hier auch mache, dann funktioniert das ganze Skript nicht mehr. Gibt es eigentlich irgendwas, das etwas mehr an Fehlerbehandlung bietet, als die Browser-Console?
Im Internet habe ich noch etwas von `$.ajax` gelesen und noch von 'fetch'.
Letzteres habe ich mal versucht, hatte damit auch Erfolg:
Gibt es irgendwelche Vor- und Nachteile? Mit was soll ich sinnvollerweise weiter machen? Ich muss ja nachher auch wieder die berechneten Daten empfangen. Nur weil ich das mit `fetch` im Testprogramm hinbekommen habe, will ich das nicht zwangsläufig verwenden, falls es Gründe gibt, die dagegen sprechen?
Vielen Dank und Grüße
Dennis
habe es geschafft, dass die Seite alle Eingabefelder ink. der Gasmischung in JavaScript validiert. Hat mich nur 5 Nervenzusammenbrüche gekostet und aus den Haaren auf dem Schreibtisch, kann man zumindest einen kleinen Besen machen.
Nun müssen die Daten Richtung Flask-App geschickt werden. In meinem Tutorial wird dafür `axios` importiert. Wenn ich das hier auch mache, dann funktioniert das ganze Skript nicht mehr. Gibt es eigentlich irgendwas, das etwas mehr an Fehlerbehandlung bietet, als die Browser-Console?
Im Internet habe ich noch etwas von `$.ajax` gelesen und noch von 'fetch'.
Letzteres habe ich mal versucht, hatte damit auch Erfolg:
Code: Alles auswählen
<html>
<head>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
</head>
<body>
<div id="app">
<h2>Eingabe</h2>
<input v-model="user_entry">
<button @click="to_python">Send</button>
</div>
<script>
const { createApp, ref } = Vue
createApp({
setup() {
const user_entry = ref("")
function to_python() {
fetch('http://localhost:5000/index', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({"eingabe": user_entry.value})
})
}
return {
to_python,
user_entry,
}
}
}).mount('#app')
</script>
</body>
</html>
Vielen Dank und Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
- __blackjack__
- User
- Beiträge: 13218
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
Da fehlt noch so ein bisschen ``await`` und Behandlung der Antwort, also Fehlerbehandlung. Es sei denn das soll wirklich „fire & forget“ sein, und es ist egal falls da irgend etwas schief läuft.
“There will always be things we wish to say in our programs that in all known languages can only be said poorly.” — Alan J. Perlis
Guten Morgen und danke für den Hinweis.
Nee, das soll ordentlich werden, mit allem was dazu gehört. Die Frage für mich ist nur, wie?
`await` kann ich im Zusammenhang mit JavaScript mal googln.
Grüße
Dennis
Nee, das soll ordentlich werden, mit allem was dazu gehört. Die Frage für mich ist nur, wie?
`await` kann ich im Zusammenhang mit JavaScript mal googln.
Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
- __blackjack__
- User
- Beiträge: 13218
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@Dennis89: Das ist im Grunde wie ``await`` in Python. Und `fetch()` liefert ein Promise für ein `Response`-Objekt, das so ähnlich ist wie in Python `requests.Response`. Man kann da beispielsweise schauen ob das `ok`-Attribut ``true`` ist.
“There will always be things we wish to say in our programs that in all known languages can only be said poorly.” — Alan J. Perlis
Danke für die Antwort und sorry für meine späte Rückmeldung. Musste das Projekt etwas hinten anstellen.
Für `await` und `async` gibt es viele Beispiele. Das Senden funktioniert weiterhin, ich frage mich nur, was kann denn da schief gehen und wie reagiere ich da sinnvoll darauf?
Ich hab die *.html-Datei mal so erweitert:
Fehlt da noch was oder wie kann ich Fehler simulieren, die auftreten können, damit ich eine Fehlerbehandlung einbauen kann?
Danke und Grüße
Dennis
Für `await` und `async` gibt es viele Beispiele. Das Senden funktioniert weiterhin, ich frage mich nur, was kann denn da schief gehen und wie reagiere ich da sinnvoll darauf?
Ich hab die *.html-Datei mal so erweitert:
Code: Alles auswählen
<html>
<head>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
</head>
<body>
<div id="app">
<h2>Eingabe</h2>
<input v-model="user_entry">
<button @click="to_python">Send</button>
</div>
<script>
const { createApp, ref } = Vue
createApp({
setup() {
const user_entry = ref("")
async function to_python() {
const response = await fetch('http://localhost:5000/index', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({"eingabe": user_entry.value})
})
if (!response.ok) {
console.log("Irgendwas ging schief, aber was?");
}
}
return {
to_python,
user_entry,
}
}
}).mount('#app')
</script>
</body>
</html>
Danke und Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
- __blackjack__
- User
- Beiträge: 13218
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@Dennis89: 404 wenn die Seite nicht gefunden wird, irgend ein 500er wenn das Programm was die Daten entgegen nimmt in eine Ausnahme läuft, … die üblichen Sachen halt.
“There will always be things we wish to say in our programs that in all known languages can only be said poorly.” — Alan J. Perlis
Guten Morgen und Danke,
gestern Abend habe ich in der Python-Funktion `index` einfach mal das `return` weggelassen, so dass folgende Aufnahme auftritt:
Hätte dann jetzt in der Browser-Console nicht mein Text "Irgendwas ging schief, aber was?" auftauchen müssen?
Grüße
Dennis
gestern Abend habe ich in der Python-Funktion `index` einfach mal das `return` weggelassen, so dass folgende Aufnahme auftritt:
Code: Alles auswählen
TypeError: The view function for 'App:index' did not return a valid response. The function either returned None or ended without a return statement.
127.0.0.1 - - [10/May/2024 09:02:02] "POST /index HTTP/1.1" 500 -
Hätte dann jetzt in der Browser-Console nicht mein Text "Irgendwas ging schief, aber was?" auftauchen müssen?
Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
Danke für die Antwort. Dann werde ich für verschiedene Fälle, passende Meldungen vorbereiten.
Mein vorheriger Beitrag war Quatsch, natürlich wird in der Browser-Console meine Meldung angezeigt. Ich hatte noch den Code geändert und nicht vollständig auf den hier geposteten zurück gesetzt. Da war meine Unachtsamkeit schuld.
Grüße
Dennis
Mein vorheriger Beitrag war Quatsch, natürlich wird in der Browser-Console meine Meldung angezeigt. Ich hatte noch den Code geändert und nicht vollständig auf den hier geposteten zurück gesetzt. Da war meine Unachtsamkeit schuld.
Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
Guten Abend,
ich verstehe schon wieder etwas nicht und bitte euch, mir zu helfen.
Ich habe `Data.json` erstellt, mit folgendem Beispielinhalt:
Eine Python-Flask-Datei mit der ich meine einzelnen Schritte durchspiele:
Und diese *.html - Datei:
Ich möchte "nachher" den Wert von `name` aus meiner `Data.json` in ein Dropdown-Menü anzeigen.
Als ich mir die ankommenden Daten in der Funktion `getTypes` angeschaut habe, habe ich mich eigentlich gefreut, weil das so aussah:
Super, da kann ich sicherlich einfach durch iterieren.
Also habe ich das Arry zurückgegeben und an `Types` gebunden. Doch `Types` ist plötzlich kein Array mehr. Zumindest zeigt mir die Console ein `Promise` - Objekt an:
Ich sehe dass da das Array drin ist. Aber erst würde ich gerne verstehen, wieso das so ist?
Wie komme ich jetzt an das Array?
Konnte eigentlich nur raten und weder `Types.value` oder `Types['value']` liefert etwas bzw. es liefert beides mal ein "undefined".
Vielen Dank und Grüße
Dennis
ich verstehe schon wieder etwas nicht und bitte euch, mir zu helfen.
Ich habe `Data.json` erstellt, mit folgendem Beispielinhalt:
Code: Alles auswählen
[
{
"name": "Typ A",
"size": 100,
},
{
"name": "Typ B",
"size": 200,
},
]
Code: Alles auswählen
#!/usr/bin/env python
from json import loads
from pathlib import Path
from flask import Flask, jsonify
from flask_classful import FlaskView, request, route
from flask_cors import CORS
DATA_FILE = Path(__file__).parent / "TechnicalData/Data.json"
class App(FlaskView):
def __init__(self, cooler_data):
self.cooler_data = cooler_data
@route("/get_data", methods=["GET"])
def get_data(self):
if request.method == "GET":
return self.cooler_data
def main():
app = Flask(__name__)
app.config.from_object(__name__)
CORS(app, resources={r"/*": {"origins": "*"}})
App.register(
app, route_base="/", init_argument=loads(DATA_FILE.read_bytes())
)
app.run()
if __name__ == "__main__":
main()
Code: Alles auswählen
<html>
<head>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
</head>
<body>
<div id="app">
</div>
<script>
const { createApp, ref } = Vue
createApp({
setup() {
async function getTypes(){
const response = await fetch('http://localhost:5000/get_data');
const data = await response.json();
console.log(data)
return data;
}
Types = getTypes();
console.log(Types);
return {
}
}
}).mount('#app')
</script>
</body>
</html>
Als ich mir die ankommenden Daten in der Funktion `getTypes` angeschaut habe, habe ich mich eigentlich gefreut, weil das so aussah:
Code: Alles auswählen
Array(8) [ {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…} ]
Also habe ich das Arry zurückgegeben und an `Types` gebunden. Doch `Types` ist plötzlich kein Array mehr. Zumindest zeigt mir die Console ein `Promise` - Objekt an:
Code: Alles auswählen
Promise { <state>: "pending" }
<state>: "fulfilled"
<value>: Array(8) [ {…}, {…}, {…}, … ]
<prototype>: Promise.prototype { … }
Wie komme ich jetzt an das Array?
Konnte eigentlich nur raten und weder `Types.value` oder `Types['value']` liefert etwas bzw. es liefert beides mal ein "undefined".
Vielen Dank und Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
- __blackjack__
- User
- Beiträge: 13218
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
Deine `getTypes()`-Funktion ist ``async``. Also hast Du ein `Promise` als Rückgabewert. Wenn Du auf das Ergebnis vom Promise warten möchtest, fehlt da ein ``await``.
“There will always be things we wish to say in our programs that in all known languages can only be said poorly.” — Alan J. Perlis
Guten Morgen,
danke für den Hinweis. Ich kann `await` nur in einer `async` - Funktion verwenden (habe ich zumindest so gelesen), dann habe ich eigentlich nur noch eine Stelle, an der ein `await` Platz hätte:
Aber das sieht falsch aus, weil ich warte ja schon auf `data`? Habs natürlich getestet, bringt aber keine Veränderung.
Ich bin auch davon ausgegangen, dass ich mit den `await` die ich schon drin habe, auf das Ergebnis warte.
Damit ich da von Anfang an keinen Denkfehler habe, ich habe das so verstanden, dass `await` die Funktion so lange pausiert, bis da ein Rückgabewert kommt oder eventuell ein Timeout.
Deine Aussage, dass da immer ein `Promise` - Objekt zurückgegeben wird, habe ich jetzt auch hier gefunden:
https://developer.mozilla.org/en-US/doc ... c_function
Aber entweder lese ich zu schlampig, verstehe es nicht oder finde keinen Weg, wie ich den Wert zurückgeben kann.
Grüße
Dennis
danke für den Hinweis. Ich kann `await` nur in einer `async` - Funktion verwenden (habe ich zumindest so gelesen), dann habe ich eigentlich nur noch eine Stelle, an der ein `await` Platz hätte:
Code: Alles auswählen
async function getTypes(){
const response = await fetch('http://localhost:5000/get_data');
const data = await response.json();
console.log(data)
return await data;
}
Ich bin auch davon ausgegangen, dass ich mit den `await` die ich schon drin habe, auf das Ergebnis warte.
Damit ich da von Anfang an keinen Denkfehler habe, ich habe das so verstanden, dass `await` die Funktion so lange pausiert, bis da ein Rückgabewert kommt oder eventuell ein Timeout.
Deine Aussage, dass da immer ein `Promise` - Objekt zurückgegeben wird, habe ich jetzt auch hier gefunden:
https://developer.mozilla.org/en-US/doc ... c_function
Aber entweder lese ich zu schlampig, verstehe es nicht oder finde keinen Weg, wie ich den Wert zurückgeben kann.
Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
@Dennis89: async ist wie unter Python kooperativ, das heißt, wenn eine Async-Funktion wartet, kann die andere, deren Ergebnis da ist, weitermachen. Dazu müssen aber alle Funktionen bis hoch zu einer "Main"-Funktion asynchron arbeiten. Bei Python ist das explizit über das Aufrufen vom Eventloop gelöst, in Javascript, das eh komplett Event-basiert arbeitet, ist der Eventloop versteckt.
Die meiner Meinung nach verständlichste Lösung ist das Füllen der Variablen außerhalb von setup über das onMounted-Event
Die meiner Meinung nach verständlichste Lösung ist das Füllen der Variablen außerhalb von setup über das onMounted-Event
Code: Alles auswählen
const { createApp, ref, onMounted } = Vue
createApp({
setup() {
types = ref([])
onMounted(async () => {
const response = await fetch('/get_data');
types.value = await response.json();
})
return {
types
}
}
}).mount('#app')
Danke für eure Antworten und Erklärungen.
Die Lösung funktioniert.
Ich verstehe das `onMounted` - Event und das macht ja auf jeden Fall Sinn, weil ich die Daten von Anfang an benötige.
Eigentlich hätte ich das so auch in meiner Funktion machen können? Unschön ist halt der Funktionsaufruf, der dann einfach irgendwo steht.
Grüße
Dennis
Die Lösung funktioniert.
Ich verstehe das `onMounted` - Event und das macht ja auf jeden Fall Sinn, weil ich die Daten von Anfang an benötige.
Eigentlich hätte ich das so auch in meiner Funktion machen können? Unschön ist halt der Funktionsaufruf, der dann einfach irgendwo steht.
Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
Nein, Du hast die Daten nicht von Anfang an, weil sie asynchron nachgeladen werden.
Und Du brauchst diesen "Funktionsaufruf", weil Du ja die Daten asynchron laden mußt.
Eventbasierte und Nebenläufige Programmierung sind halt schwierige Themen, um die man aber nicht herum kommt, sobald man eine Server/Client-Architektur hat. Und das ist halt die Lösung in Javascript.
Und Du brauchst diesen "Funktionsaufruf", weil Du ja die Daten asynchron laden mußt.
Eventbasierte und Nebenläufige Programmierung sind halt schwierige Themen, um die man aber nicht herum kommt, sobald man eine Server/Client-Architektur hat. Und das ist halt die Lösung in Javascript.
Da habe ich mich schlecht ausgedrückt. Ich habe das so verstanden: Der `onMounted` - Event wird zu Beginn, ich denke mal mit `.mount('#app')` ausgelöst und dann werden die Daten geladen. Während dessen können aber andere Sachen ausgeführt werden, weil `await` wartet, bis die Daten da sind.
Mit "von Anfang an" meinte ich, dass die Daten nicht erst geladen werden, wenn der User aktiv ein Event (Bspw. Buttonklick) auslöst.
Mit nebenläufiger Programmierung hatte ich noch nie wirklich Kontaktpunkte. Ich lese zwar in den Themen hier im Forum immer mit, aber um zu verstehen, muss ich es anwenden. Von dem her bin ich eigentlich ganz froh darüber, dass ich das anwenden muss. Wenn eure Nerven das auch mit machen, dann bin ich optimistisch
Grüße
Dennis
Mit "von Anfang an" meinte ich, dass die Daten nicht erst geladen werden, wenn der User aktiv ein Event (Bspw. Buttonklick) auslöst.
Mit nebenläufiger Programmierung hatte ich noch nie wirklich Kontaktpunkte. Ich lese zwar in den Themen hier im Forum immer mit, aber um zu verstehen, muss ich es anwenden. Von dem her bin ich eigentlich ganz froh darüber, dass ich das anwenden muss. Wenn eure Nerven das auch mit machen, dann bin ich optimistisch
Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
Guten Morgen,
ich bin nun soweit, dass alle notwendigen Daten eingegeben werden können und per JavaScript validiert werden. Wenn alle Werte in meinem vorgegebenen Bereich liegen und auch alle Eingabefelder ausgefüllt sind, wird ein Button aktiviert und damit schicke ich alle Daten an mein Python-Programm. Jetzt habe ich aber folgendes Zitat noch im Hinterkopf:
Meine eigentliche Frage, die ich schon mal bei PyQt hatte, dort aber mit dem `Validator` umgehen konnte, ist folgendes:
Eine Funktion macht immer eine Tätigkeit, also schreibe ich im einfachsten Fall eine Funktion und nenne sie zum Beispiel `is_float`. Die nimmt einen Wert entgegen, mit `try/except` wird versucht ihn in einen `float`-Typ zu wandeln und je nach Erfolg gibt sie `True` oder `False` zurück.
Danach weis ich, ob meine Eingabewerte richtig sind, sie liegen mir aber immer noch als Strings vor, dann muss ich eine weitere Funktion `convert_to_float` schreiben und habe eigentlich wieder sehr ähnlichen Code wie in `is_float`.
Beides in einer Funktion zu machen, würde dem Grundsatz "Eine Funktion macht eine Tätigkeit" widersprechen, aber man schreibt auch keinen doppelten oder sehr ähnlichen Code. Was wäre denn eine sinnvolle Vorgehensweise?
Vielen Dank und Grüße
Dennis
ich bin nun soweit, dass alle notwendigen Daten eingegeben werden können und per JavaScript validiert werden. Wenn alle Werte in meinem vorgegebenen Bereich liegen und auch alle Eingabefelder ausgefüllt sind, wird ein Button aktiviert und damit schicke ich alle Daten an mein Python-Programm. Jetzt habe ich aber folgendes Zitat noch im Hinterkopf:
Alles noch mal in Python zu validieren, macht man, damit das Programm unabhängig von der Webseite ist?
Meine eigentliche Frage, die ich schon mal bei PyQt hatte, dort aber mit dem `Validator` umgehen konnte, ist folgendes:
Eine Funktion macht immer eine Tätigkeit, also schreibe ich im einfachsten Fall eine Funktion und nenne sie zum Beispiel `is_float`. Die nimmt einen Wert entgegen, mit `try/except` wird versucht ihn in einen `float`-Typ zu wandeln und je nach Erfolg gibt sie `True` oder `False` zurück.
Danach weis ich, ob meine Eingabewerte richtig sind, sie liegen mir aber immer noch als Strings vor, dann muss ich eine weitere Funktion `convert_to_float` schreiben und habe eigentlich wieder sehr ähnlichen Code wie in `is_float`.
Beides in einer Funktion zu machen, würde dem Grundsatz "Eine Funktion macht eine Tätigkeit" widersprechen, aber man schreibt auch keinen doppelten oder sehr ähnlichen Code. Was wäre denn eine sinnvolle Vorgehensweise?
Vielen Dank und Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]