Fetch-api OpenWeather, problem to acess attribute 'name' value and display it - javascript

My question is, I can display both 'description' and 'temp', so, why can't I retrieve the 'name' of the city. Please look at a fetch response:
var button = document.querySelector('.button')
var inputValue = document.querySelector('.inputValue')
var name = document.querySelector('.name');
var desc = document.querySelector('.desc');
var temp = document.querySelector('.temp');
//trigering Action Fetch api
button.addEventListener('click',function(){
fetch ('https://api.openweathermap.org/data/2.5/weather?q='+inputValue.value+'&appid=0f91ec65ce9099b9b43a35a9f89f6f26')
.then(response => response.json())
.then(data => {
var nameValue = data['name'];
var tempValue = data['main']['temp'];
var descValue = data['weather'][0]['description'];
name.innerHTML = nameValue;
temp.innerHTML = tempValue;
desc.innerHTML = descValue;
})
.catch(err => alert("Wrong city name!"))
})
{
"coord": {
"lon": 145.77,
"lat": -16.92
},
"weather": [{
"id": 802,
"main": "Clouds",
"description": "scattered clouds",
"icon": "03n"
}],
"base": "stations",
"main": {
"temp": 300.15,
"pressure": 1007,
"humidity": 74,
"temp_min": 300.15,
"temp_max": 300.15
},
"visibility": 10000,
"wind": {
"speed": 3.6,
"deg": 160
},
"clouds": {
"all": 40
},
"dt": 1485790200,
"sys": {
"type": 1,
"id": 8166,
"message": 0.2064,
"country": "AU",
"sunrise": 1485720272,
"sunset": 1485766550
},
"id": 2172797,
"name": "Cairns",
"cod": 200
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
</html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="style.css"/>
<title>Request APP template</title>
</head>
<h1>Simple weather App</h1>
<body>
<div class="input">
<input type="text" class="inputValue" placeholder="Enter a city">
<input type="submit" value="Submit" class="button"></div>
</div>
<div>
<h1>
Current city weather conditions:
</h1>
</div>
<div class="display">
<h1 class="name"></h1>
<p class="desc"></p>
<p class="temp"></p>
<i class="icon"></p>
</div>
<script src="app.js"></script>
</body>
</html>
Am I wrong at var nameValue = data['name']? am I missing something?
thanks in advance
I am looking forward to learning how to use fetch correctly to improve my projects.

Related

I can't select a row from a DataTable

I have a DataTable that is created dynamically according to the result of a SELECT, the first time it is created it does not give me any problem, but when I change the SELECT, still reloading the table, the data of it cannot be accessed
In the browser console appears this error message:
Uncaught TypeError: can't access property "name", informe is undefined
file:///C:/Users/jordi.burgos/Downloads/ejemplo minimo/index.js:40
jQuery 8
file:///C:/Users/jordi.burgos/Downloads/ejemplo minimo/index.js:36
jQuery 2
You can see this error in https://codepen.io/jordibonarea/pen/OJvNOZB
I have created a minimum code to be able to model the example:
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Ejemplo mínimo</title>
<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
<!-- DataTables -->
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.12.1/css/jquery.dataTables.css">
<script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/1.12.1/js/jquery.dataTables.js"></script>
<script src="index.js"></script>
</head>
<body>
<h1>Este es el ejemplo mínimo para que de error el DataTable</h1>
<select name="prueba_select" id="prueba_select">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>
<table id="table_prueba"></table>
<div id="item_selected"> </div>
</body>
</html>
index.js
$(document).ready(function () {
$('#prueba_select').change(function (e) {
e.preventDefault();
var $tabla_modal_informes = $('#table_prueba').DataTable({
destroy: true,
"data": [
{
"name": "Tiger Nixon",
"position": "System Architect",
"salary": "$3,120",
"start_date": "2011/04/25",
"office": "Edinburgh",
"extn": 5421
},
{
"name": "Garrett Winters",
"position": "Director",
"salary": "5300",
"start_date": "2011/07/25",
"office": "Edinburgh",
"extn": "8422"
},
// ...
],
"columns": [
{ "data": "name" },
{ "data": "position" },
{ "data": "office" },
{ "data": "extn" },
{ "data": "start_date" },
{ "data": "salary" }
]
});
//cuando hacemos click en sus filas
$('#table_prueba').on('click','tr',function () {
//$tabla_modal_informes.rows().deselect();
// Ontiene datos de la fila seleccionada
let informe = $tabla_modal_informes.row(this).data();
$('#item_selected').html('<h3>' + informe.name +'</h3>');
});
});
});
Thanks
I just changed the scope where $table_modal_informes is defined putting its declaration outside of the ready event handler so that you'll have only one reference to one DataTable object at any given time.
As you can see in the snippet, now you are free to select rows from the table any time also after the selected data table was changed from the corresponding dropdown:
var $tabla_modal_informes;
$(document).ready(function () {
$('#prueba_select').change(function (e) {
e.preventDefault();
$tabla_modal_informes = $('#table_prueba').DataTable({
destroy: true,
"data": [
{
"name": "Tiger Nixon",
"position": "System Architect",
"salary": "$3,120",
"start_date": "2011/04/25",
"office": "Edinburgh",
"extn": 5421
},
{
"name": "Garrett Winters",
"position": "Director",
"salary": "5300",
"start_date": "2011/07/25",
"office": "Edinburgh",
"extn": "8422"
},
// ...
],
"columns": [
{ "data": "name" },
{ "data": "position" },
{ "data": "office" },
{ "data": "extn" },
{ "data": "start_date" },
{ "data": "salary" }
]
});
//cuando hacemos click en sus filas
$('#table_prueba').on('click','tr',function (event) {
//$tabla_modal_informes.rows().deselect();
// Ontiene datos de la fila seleccionada
let informe = $tabla_modal_informes.row(this).data();
$('#item_selected').html('<h3>' + informe.name +'</h3>');
});
});
});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Ejemplo mínimo</title>
<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
<!-- DataTables -->
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.12.1/css/jquery.dataTables.css">
<script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/1.12.1/js/jquery.dataTables.js"></script>
</head>
<body>
<h1>Este es el ejemplo mínimo para que de error el DataTable</h1>
<select name="prueba_select" id="prueba_select">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>
<table id="table_prueba"></table>
<div id="item_selected"> </div>
</body>
</html>

Need to generate a file based on form input and download it (FormIO)

I'm trying to make a system that generates a file based on the selection in a form. Currently I use FormIO to generate the forms from a json structure. FormIO form builder
So when I press submit it would download a file with my selected values.
I know it already generates the object. But I don't know how to filter it with this.
Right now it generates the file with this in it. But I would like to only have the radio button value and the name.
{"data":{"radio2":1,"howLongShouldItWait":12,"submit":true},"metadata":{"timezone":"Europe/Brussels","offset":60,"referrer":"","browserName":"Netscape","userAgent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:65.0) Gecko/20100101 Firefox/65.0","pathName":"/C:/Users/Jan/Desktop/IPP_conf/index.html","onLine":true},"state":"submitted","saved":false}
So what I eventually want is something like this
#define WAIT_TIME 3
#define OVERRIDE_BUTN
The js function to download the file and the JSON part.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="description" content="">
<meta name="author" content="">
<link rel="shortcut icon" href="favicon.ico" type="image/x-icon">
<title>Configuration form</title>
<!-- Bootstrap core CSS -->
<link href="vendor/bootstrap/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css">
<link rel="stylesheet" href="https://unpkg.com/formiojs#latest/dist/formio.full.min.css">
<script src="https://unpkg.com/formiojs#latest/dist/formio.full.min.js"></script>
</head>
<body>
<!-- Navigation -->
<nav class="navbar navbar-expand-lg navbar-dark bg-dark static-top">
<div class="container">
<a class="navbar-brand" href="#">
<img src="resources/logo64x64.png" alt="">
</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarResponsive"
aria-controls="navbarResponsive" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarResponsive">
<ul class="navbar-nav ml-auto">
<li class="nav-item active">
<a class="nav-link" href="#">Home
<span class="sr-only">(current)</span>
</a>
</li>
</ul>
</div>
</div>
</nav>
<!-- Page Content -->
<div class="container">
<div class="row">
<div class="col-lg-12 text-center">
<h1 class="mt-5">Settings</h1>
<div id="formio"></formio>
</div>
</div>
<!-- Bootstrap core JavaScript -->
<script src="vendor/jquery/jquery.min.js"></script>
<script src="vendor/bootstrap/js/bootstrap.bundle.min.js"></script>
<script>
Formio.icons = 'fontawesome';
Formio.createForm(document.getElementById('formio'), {
"display": "form",
"components": [
{
"label": "Test",
"optionsLabelPosition": "right",
"values": [
{
"label": "Yes",
"value": "1",
"shortcut": ""
},
{
"label": "No",
"value": "0",
"shortcut": ""
}
],
"inline": true,
"mask": false,
"tableView": true,
"alwaysEnabled": false,
"type": "radio",
"input": true,
"key": "radio2",
"defaultValue": 1,
"validate": {
"customMessage": "",
"json": ""
},
"conditional": {
"show": "",
"when": "",
"json": ""
},
"encrypted": false,
"properties": {},
"customConditional": "",
"logic": [],
"reorder": false
},
{
"label": "How long should it wait?",
"optionsLabelPosition": "right",
"values": [
{
"label": "1 Hour",
"value": "1",
"shortcut": ""
},
{
"label": "12 Hours",
"value": "12",
"shortcut": ""
}
],
"inline": true,
"mask": false,
"tableView": true,
"alwaysEnabled": false,
"type": "radio",
"input": true,
"key": "howLongShouldItWait",
"defaultValue": 12,
"validate": {
"customMessage": "",
"json": ""
},
"conditional": {
"show": "",
"when": "",
"json": ""
},
"encrypted": false,
"reorder": false,
"properties": {},
"customConditional": "",
"logic": []
},
{
"label": "Generate",
"state": "",
"theme": "primary",
"shortcut": "",
"disableOnInvalid": true,
"mask": false,
"tableView": true,
"alwaysEnabled": false,
"type": "button",
"key": "submit",
"input": true,
"defaultValue": false,
"validate": {
"customMessage": "",
"json": ""
},
"conditional": {
"show": "",
"when": "",
"json": ""
},
"encrypted": false,
"properties": {
"test": "5"
},
"tags": [],
"showValidations": false,
"event": "",
"url": "",
"custom": "",
"reorder": false,
"customConditional": "",
"logic": []
}
],
}).then(function (form) {
var filename = "settings.h";
function download(filename, text) {
var element = document.createElement('a');
element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));
element.setAttribute('download', filename);
element.style.display = 'none';
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
}
form.on('submit', function (submission) {
console.log(submission);
download(filename, JSON.stringify(submission));
});
});</script>
</body>
</html>
I tried a for loop on the submission variable. But I don't know how to select the exact data.
Kind regards and thanks in advance
I still have to filter it properly but I got the data i needed, I was looking a bit too far. Instead of using the custom submission endpoint link, there was another simpler way.
for(key in submission.data){
//Do stuff where key would be 0 and value would be the object
console.log(key + ' ' + submission.data[key] );
}
This I can now filter to my needs. I tried getting the data straight out of 'submission' so I was on the right path.

v-on:click event Vue.js to show user posts

I'm a student and I'm just getting into Vue.js so I'm still very new to it. Right now I'm making a project where I'm getting usernames from an API and when you click on the user it has to show the related post, but this is not working. When I click the button with the v-on:click event. nothing happens, not even in the console. So I hope someone can help me with my problem, I would really appreciate it.
main.js :
const app = new Vue({
el: "#app",
data: {
users: [],
posts: [],
},
methods: {
Showpost(id, i) {
fetch("https://jsonplaceholder.typicode.com/posts?userId=" + id)
.then(response =>response.json())
.then((data) => {
this.posts = data;
})
},
},
mounted() {
fetch("https://jsonplaceholder.typicode.com/users")
.then(response => response.json())
.then((data) => {
this.users = data;
})
},
template: `
<div>
<td v-for="user, i in users">
<button v-on:click="Showpost(user.id, i)" >{{ user.name }}</button>
</td>
<h1>{{ posts.title }}</h1>
</div>
`,
});
html :
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css">
<title>Users</title>
</head>
<body>
<h1>Users</h1>
<div id="app">
</div>
<script src="https://unpkg.com/vue"></script>
<script src="./main.js"></script>
</body>
</html>
json users :
{
"id": 1,
"name": "Leanne Graham",
"username": "Bret",
"email": "Sincere#april.biz",
"address": {
"street": "Kulas Light",
"suite": "Apt. 556",
"city": "Gwenborough",
"zipcode": "92998-3874",
"geo": {
"lat": "-37.3159",
"lng": "81.1496"
}
},
"phone": "1-770-736-8031 x56442",
"website": "hildegard.org",
"company": {
"name": "Romaguera-Crona",
"catchPhrase": "Multi-layered client-server neural-net",
"bs": "harness real-time e-markets"
}
}
json posts :
{
"userId": 1,
"id": 1,
"title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
"body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
}
Try to create a property called post and update it on every click on a specified user by assigning this.post=data[i]:
new Vue({
el: "#app",
data: {
users: [],
posts: [],
post: ''
},
methods: {
Showpost(id, i) {
fetch("https://jsonplaceholder.typicode.com/posts?userId=" + id)
.then(response => response.json())
.then((data) => {
this.post = data[i];
})
},
},
mounted() {
fetch("https://jsonplaceholder.typicode.com/users")
.then(response => response.json())
.then((data) => {
this.users = data;
})
},
template: `
<div class="flex">
<div v-for="user, i in users">
<button class="btn" v-on:click="Showpost(user.id, i)" >{{ user.name }}</button>
</div>
<h1>{{ post.title }}</h1>
</div>
`,
});
.flex{
display:flex;
flex-wrap:wrap;
}
<!DOCTYPE html>
<html>
<head>
<meta name="description" content="Vue.delete">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.2.1/vue.min.js"></script>
</head>
<body>
<div id="app">
</div>

View output doesn't show up

I'm working on the tutorial to display contact details on my page. The code doesn't display the first and last name. Please find the code below.
My index.html
<!DOCTYPE html>
<html data-ng-app="myContactApp">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.6/angular.min.js"></script>
<script src="app.js"></script>
<title>My Contact Application</title>
</head>
<body>
<h1>Contact App</h1>
<div data-ng-controller="contactController as ctrl">
<div data-ng-repeat="con in ctrl.contactArr">
<span>{{con.name.first+ " "+con.name.last}}</span>
</div>
</div>
</body>
</html>
My app.js file
var app=angular.module("myContactApp",[]);
app.controller("contactController",contactCtrl);
function contactCtrl(){
this.contactArr = [
{
"gender": "male",
"name": {
"title": "mr",
"first": "romain",
"last": "hoogmoed"
},
"location": {
"street": "1861 jan pieterszoon coenstraat",
"city": "maasdriel",
"state": "zeeland",
"postcode": 69217
},
"email": "romain.hoogmoed#example.com",
"login": {
"username": "lazyduck408",
"password": "jokers",
"salt": "UGtRFz4N",
"md5": "6d83a8c084731ee73eb5f9398b923183",
"sha1": "cb21097d8c430f2716538e365447910d90476f6e",
"sha256": "5a9b09c86195b8d8b01ee219d7d9794e2abb6641a2351850c49c309f1fc204a0"
},
"dob": "1983-07-14 07:29:45",
"registered": "2010-09-24 02:10:42",
"phone": "(656)-976-4980",
"cell": "(065)-247-9303",
"id": {
"name": "BSN",
"value": "04242023"
},
"picture": {
"large": "https://randomuser.me/api/portraits/men/83.jpg",
"medium": "https://randomuser.me/api/portraits/med/men/83.jpg",
"thumbnail": "https://randomuser.me/api/portraits/thumb/men/83.jpg"
},
"nat": "NL"
}
]
}
My page is not showing the first and last name when I run through HTTP-server. Am I doing anything wrong?
Your code works fine. Kindly see whether app.js or angular dependency properly loaded or not.
https://jsfiddle.net/Prasanna15/m3q70umq/
you can check your code.
try to use https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.5/angular.min.js this one
Your code runs like a charm. There is no mistake in it. Please ensure that all ressources (app.js & https://ajax.googleapis.com/ajax/libs/angularjs/1.6.6/angular.min.js) are loaded. Open up the network tab in your browser debugger to check this. Also ensure you cleaned up your browser cache.
<!DOCTYPE html>
<html data-ng-app="myContactApp">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.6/angular.min.js"></script>
<script src="app.js"></script>
<title>My Contact Application</title>
</head>
<body>
<h1>Contact App</h1>
<div data-ng-controller="contactController as ctrl">
<div data-ng-repeat="con in ctrl.contactArr">
<span>{{con.name.first+ " "+con.name.last}}</span>
</div>
</div>
</body>
</html>
--> demo fiddle

ng-model naming issue, trying to build an array but got hash instead

I'm trying to build an array with ng-model,
<div ng-repeat="n in [1, 2, 3]">
<input type="text" class="form-control" ng-model="headers[$index].key">
<input type="text" class="form-control" ng-model="headers[$index].value">
</div>
When I do angular.toJson ($scope.headers), I got:
{
"headers": {
"0": {
"key": "xxx",
"value": "yyy"
}
}
}
But I wanted this,
{
"headers": [
{
"key": "xxx",
"value": "yyy"
}
]
}
Is it impossible to get that?
Is this what you mean?
DEMO
index.js
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js#1.4.x" src="https://code.angularjs.org/1.4.2/angular.js" data-semver="1.4.2"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
<div ng-repeat="object in transformedData">
<input type="text" class="form-control" ng-model="object.key">
<input type="text" class="form-control" ng-model="object.value">
</div>
<pre>{{transformedData}}</pre>
</body>
</html>
app.js
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
var data = {
"headers": {
"0": {
"key": "xxx",
"value": "yyy"
}
}
};
$scope.transformedData = transformData(data.headers)
function transformData(data){
var arr = [];
for(var key in data){
arr.push(data[key])
}
return arr;
}
});
You just need to initialize your header as an array and ng-model assignments will work.
I have altered the plunker shared by #Matt, check it here
http://plnkr.co/edit/z6Cz6R3gZpDCsXSUmIEG?p=preview

Categories

Resources