В Mithril обработка ответов от серверных API строится вокруг
встроенного модуля m.request, который
упрощает работу с HTTP-запросами. Основная задача — получить данные,
корректно их обработать и интегрировать в компоненты интерфейса.
m.request({
method: "GET",
url: "/api/data"
}).then(function(result) {
console.log(result);
}).catch(function(e) {
console.error(e);
});
Ключевые моменты:
m.request возвращает Promise, что
позволяет использовать цепочки then/catch или современный
async/await.GET, POST,
PUT, DELETE) и заголовки через
headers.data используется для передачи тела запроса при методах
POST и PUT.JSON является самым распространённым форматом обмена данными. Mithril
автоматически преобразует JSON-ответы в объект JavaScript при помощи
responseType: "json" (по умолчанию).
m.request({
method: "GET",
url: "/api/users",
responseType: "json"
}).then(function(users) {
users.forEach(user => console.log(user.name));
});
Особенности:
catch.unwrap:m.request({
method: "GET",
url: "/api/users",
unwrap: data => data.results
}).then(users => console.log(users));
Для работы с текстовыми ответами используется
responseType: "text":
m.request({
method: "GET",
url: "/api/message",
responseType: "text"
}).then(text => console.log(text));
Для бинарных данных, таких как изображения или файлы, применяется
responseType: "arraybuffer" или "blob":
m.request({
method: "GET",
url: "/api/image",
responseType: "blob"
}).then(blob => {
const imgURL = URL.createObjectURL(blob);
document.querySelector("img").src = imgURL;
});
Mithril позволяет перехватывать ошибки как сетевого уровня, так и
уровня HTTP. В catch попадают все исключения, включая
неправильный JSON, ошибки сети и коды состояния, не относящиеся к
диапазону 200–299.
m.request({
method: "GET",
url: "/api/data"
})
.then(data => console.log("Данные получены:", data))
.catch(err => {
if (err.code === 404) {
console.error("Ресурс не найден");
} else {
console.error("Произошла ошибка", err);
}
});
Совет: Для проверки статуса удобно использовать
config:
m.request({
method: "GET",
url: "/api/data",
config: xhr => {
xhr.onl oad = () => {
if (xhr.status !== 200) {
console.warn("Статус ответа:", xhr.status);
}
};
}
});
Mithril полностью поддерживает синтаксис async/await,
что делает код более линейным и читаемым:
async function loadUsers() {
try {
const users = await m.request({
method: "GET",
url: "/api/users"
});
console.log(users);
} catch (err) {
console.error("Ошибка загрузки пользователей", err);
}
}
Если сервер возвращает данные в специфическом формате (например, CSV
или XML), нужно использовать responseType: "text" и
самостоятельно парсить содержимое:
m.request({
method: "GET",
url: "/api/data.csv",
responseType: "text"
}).then(csvText => {
const rows = csvText.split("\n").map(row => row.split(","));
console.log(rows);
});
Результаты запросов удобно сохранять в свойствах компонентов для реактивного обновления интерфейса:
const UserList = {
users: [],
oninit: async function() {
this.users = await m.request({ method: "GET", url: "/api/users" });
},
view: function() {
return m("ul", this.users.map(user => m("li", user.name)));
}
};
Особенности интеграции:
Promise.all
для параллельной загрузки данных.oninit: async function() {
const [users, posts] = await Promise.all([
m.request({ method: "GET", url: "/api/users" }),
m.request({ method: "GET", url: "/api/posts" })
]);
this.users = users;
this.posts = posts;
}
Mithril не ограничивает обработку данных: можно использовать любые функции для фильтрации, сортировки или трансформации перед отображением:
this.activeUsers = this.users.filter(u => u.active);
this.sortedUsers = this.activeUsers.sort((a, b) => a.name.localeCompare(b.name));
Это позволяет отделить логику получения данных от логики отображения, что упрощает поддержку больших приложений.