Newsgroup: it.comp.lang.javascript
Titolo: Jquery Twitter

Ciao a tutti.
Sto cercando di fare il parse di un Json di twitter da inserire in una pagina web.
Riesco a tirare fuori i tweet e sto cercando di fare un ciclo di for per sostituire gli hashtags con un link all'hashtag stesso. Ma non mi funziona. Qualcuno riesce a dirmi cosa sbaglio nel ciclo di for? Il resto funziona bene.
 
 
<div id="tweets"></div>
<script type="text/javascript" src="
http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js
"></script>
<script type="text/javascript">
var html = '';
var url = '
https://search.twitter.com/search.json?callback=?&q=%23asroma&rpp=50&include_entities=true&with_twitter_user_id=true&result_type=recent
';
var appo = '';
var appo2 = '';
var appo3 = '';
 
$.getJSON(url, function(data) {
    $.each(data.results, function(i, item) {
        var user = item.from_user;
		var img = item.profile_image_url;
        var tweet = item.text;
		appo = '<img src="' + img + '"/>' + tweet + ' user: ' + user + '<br>';
		for(item2 in item.hastags) {
			appo2 = '<a href="
https://twitter.com/#!/search/realtime/%23
' + item2.text + '">' + item2.text + '</a>';
			appo3 = '#' + item2.text;
			appo = appo.replace(appo3,appo2);
		};
        html += appo;
    });
$('#tweets').html(html);
});
</script>

Grazie mille! Mi sto studiando la differenza tra il for in e il for each. Chiaro che non ho capito la differenza.
Veramente grazie per tutti i consigli. Sto cercando una app per Chrome per fare il debug!
 
Max

 Veramente grazie per tutti i consigli. Sto cercando una app per Chrome per fare il debug!
 
Non ne hai bisogno, è già integrato. Ti basta andare sotto il menù
"View" (mi pare) e poi "Developer". Lì hai i Developer Tools, la
Javascript Console, etc.

Ciao a tutti,
stavo sperimentando quanto detto e ho provato a mettere tutto dentro un altro ciclo di for. Ma c'è qualcosa che non quadra. 
Il codice dentro il for funziona bene isolatamente.
Nella web console vedo che fa entrambe le chiamate e riceve un codice "200", per cui sono andate a buon fine. Ma poi non elabora i risultati.
Non ho ancora capito come funziona il for? 
 
Di seguito il codice, grazie.
 
 
<html>
<head>
<title>Tweets</title>
<meta charset="utf-8" />
<style type="text/css">
 
</style>
</head>
 
<body>
<div id="tweets"></div>
<script type="text/javascript" src="
http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js
"></script>
<script type="text/javascript">
var html = '';
var url = '';
var appo = '';
var appo2 = '';
var contenitore = ['grostein', 'asromaofficial'];
for (var a=0, profilo; profilo = contenitore[a++];) {
url = '
http://api.twitter.com/1/statuses/user_timeline.json?include_entities=true&include_rts=true&screen_name=
' + profilo + '&count=20';
	$.getJSON(url, function(data) {
		$.each(data, function(i, item) {
			if (item.entities.media !== undefined) {
				for (var i=0, foto; foto = item.entities.media[i++];) {
					if (appo2 !== foto.media_url) {
						appo = '<a href="' + foto.media_url + '"> <img width="120" src="' + foto.media_url  + '"/> </a>';
						appo2 = foto.media_url;
					};
				};
			};
		html += appo;
		});
	$('#tweets').append(html);
	});
};
</script>
</body>
</html>

Se qualcuno ha qualche idea.
Così funziona:
 
var html = '';
var url = '
https://api.twitter.com/1/statuses/user_timeline.json?screen_name=officialasroma&count=20&include_entities=true&callback=?
';
var appo = '';
$.getJSON(url, function(data) {
	$.each(data, function(i, item) {
		if (item.entities.media !== undefined) {
			for (var i=0, foto; foto = item.entities.media[i++];) {
				appo = '<a href="' + foto.media_url + '"> <img width="120" src="' + foto.media_url + '"/> </a>';
			};
		};
		html += appo;
	});
$('#tweets').html(html);
});
 
Dentro il for non funziona più:
 
var html = '';
var url = '';
var appo = '';
var contenitore = ['grostein', 'asromaofficial'];
for (var a=0, profilo; profilo = contenitore[a++];) {
	url = '
http://api.twitter.com/1/statuses/user_timeline.json?include_entities=true&include_rts=true&screen_name=
' + profilo + '&count=20';
	html = '';
	$.getJSON(url, function(data) {
		$.each(data, function(i, item) {
			if (item.entities.media !== undefined) {
				for (var i=0, foto; foto = item.entities.media[i++];) {
					appo = '<a href="' + foto.media_url + '"> <img width="120" src="' + foto.media_url + '"/> </a>';
				};
			};
			html += appo;
		});
		$('#tweets').append(html);
	});
};
 


 
Quindi il primo passo č, usare l'URL corretto. Quindi convertire:
 
url =
'
http://api.twitter.com/1/statuses/user_timeline.json?include_entities=true&include_rts=true&screen_name=
'
+ profilo + '&count=20';
 
Nell'URL che ti funziona, usando "profilo" come variabile.
 
Vedrai a questo punto, che la funzione passata a `getJSON`, quella che
ha "data" come parametro, viene invocata (mettendo un `console.log` al
suo interno), ma che comunque non ti visualizza niente a schermo.
 
Questo, ancora, perché hai usato due URL diversi ovvero in quello che
"ti funziona" hai come utente `officialasroma`, mentre in quello che
"non ti funziona" hai `grostein` e `asromaofficial`, che a quanto pare
non hanno nessun `media` negli ultimi 20 tweet. Infatti, se fai un
`console.log` di `item.entities.media` vedrai che  ti ritorna
`undefined` per questi due, ergo non entri mai nel ciclo che dovrebbe
generarti l'HTML.
 
Come sempre, un pochino di debug e potevi arrivarci anche da solo. :)

Mi sembra di capire che le API di Twitter fanno come gli pare a loro. Questa mattina ho fatto la modifica al volo e da telefonino vedevo la pagina bene. Adesso che sono in ufficio dal computer fisso non va più.
Cmq cercavo nel posto sbagliato, pensavo fosse colpa del for, invece era la cosa più semplice.
 
Grazie mille!!!!!!!!

Ciao,
lo script continua a non funzionare (ma dovrebbe funzionare). Sto facendo "debug" e la console mi da:
 
[14:58:09.198] SaroFiorello @ file:///C:/Users/Ies%203/Desktop/Dropbox/sitarello.html:40
[14:58:09.203] OfficialAsRoma @ file:///C:/Users/Ies%203/Desktop/Dropbox/sitarello.html:40
[14:58:09.302] GET 
http://api.twitter.com/1/statuses/user_timeline.json?include_entities=true&include_rts=true&screen_name=SaroFiorello&count=20
 [HTTP/1.1 200 OK 466ms]
[14:58:09.399] GET 
http://api.twitter.com/1/statuses/user_timeline.json?include_entities=true&include_rts=true&screen_name=OfficialAsRoma&count=20
 [HTTP/1.1 200 OK 464ms]
 
Quando invece, secondo la mia logica, dovrebbero essere alternati. Quando fa un GET dovrebbe elaborarlo e passare all'altro. Sbaglio? I cicli lavorano in contemporanea?
 
 
<body>
<div id="tweets"></div>
<script type="text/javascript" src="
http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js
"></script>
<script type="text/javascript">
var html = '';
var url = '';
var appo = '';
var contenitore = ['SaroFiorello', 'OfficialAsRoma'];
for (var a=0, profilo; profilo = contenitore[a++];) {
	html = '';
	url = '
http://api.twitter.com/1/statuses/user_timeline.json?include_entities=true&include_rts=true&screen_name=
' + profilo + '&count=20';
	html += '<div id="contenitore"> <a href="
http://www.twitter.com/
' + profilo + '/">' + profilo + '</a>';
	console.log(profilo);
	$.getJSON(url, function(data) {
		$.each(data, function(i, item) {
			if (item.entities.media !== undefined) {
				for (var i=0, foto; foto = item.entities.media[i++];) {
					appo = '<div id="blocco"><a href="' + foto.media_url + '"> <img width="120" src="' + foto.media_url + '"/> </a><br><br>' + item.text + '</div>';
					html += appo;
				};
			};
		});
		html += '</div> <br>';


 	$.getJSON(url, function(data) {
 
Qui però, dici al browser di farti una richiesta HTTP, di aspettarsi il
risultato in JSON, e passi una funzione da eseguire quando la richiesta
è completata. Pensaci un attimo, passi una funzione. Se la chiamata
fosse stata *sincrona* non avresti avuto bisogno di farlo, no? Potevi fare:
 
	var data = $.getJSON(url);
 
	$.each(data, /* etc */);
 
Invece non funziona così jQuery. Questo perché, di default le chiamate
HTTP sono asincrone. Il che significa che tu istruisci il browser di
farti una chiamata a quell'indirizzo, e quando ricevi la risposta dal
server - che potrebbe essere chissà quando - di eseguire del codice. Nel
mentre, il codice javascript procede. Il che significa, nel tuo caso,
che passi al loop successivo del ciclo, che fa un'altra richiesta HTTP.
Se la prima ci mettesse più della seconda a ritornare, potresti anche
avere il risultato della seconda prima della prima chiamata.
 
Se le due chiamate HTTP, poi, avvengono in contemporanea o meno, dipende
dalle impostazioni del browser e da quante richieste HTTP attive ci sono
in quel momento.

Mi hai aperto un mondo! Ma in questo caso la mia variabile html si incasina. Ma potrei creare div con jquery dove ospitare i risultati?

 Ma in questo caso la mia variabile html si incasina. Ma potrei creare div con jquery dove ospitare i risultati?
 
Secondo me dovresti cambiare un pelino la logica del tuo codice, e usare
un po' più di DOM. Per essere più chiari, tu hai un elemento nella
pagina che ha id "tweets". Orbene, il tuo codice dovrebbe essere
qualcosa tipo "Hey, visualizzami in questo elemento i media di questi
utenti" che si traduce in:
 
- ciclare la lista degli utenti che ti interessa
- per ognuno di essi, fare una chiamata http
- quando la chiamata http è risolta, creare l'html da aggiungere
direttamente in coda a "tweets" (le chiamate che ritornano prima saranno
aggiunte prima).
 
Riprendendo il tuo codice, devi rimuovere la variabile `html` del tutto,
e spostare la creazione del div contenitore nella risoluzione della
richiesta. Quindi, ogni risoluzione della richiesta crea il div
contenitore, lo aggiunge a tweet, poi itera i dati ricevuti e crea un
div blocco. In questo modo non dipendi da nessuna variabile esterna.
 
Nota che stai usando un ID per contenitore, ma non puoi: l'id, come
suggerisce il nome, deve essere univoco. Tu crei tanti <div
id="contenitore"> per quanti profili hai (in questo caso due). Stesso
dicasi per <div id="blocco">. Ciò che vuoi usare probabilmente sono classi.

Adesso mi sono chiare molte più cose. L'ho variato come sotto.
Adesso, sto cercando di debbuggare per capire perché si incasina il for.
 
var url = '';
var appo = '';
var contenitore = ['SaroFiorello', 'OfficialAsRoma'];
var finale = contenitore.length;
for (var a=0, profilo; profilo = contenitore[a++];) {
	url = '
https://api.twitter.com/1/statuses/user_timeline.json?screen_name=
' + profilo + '&count=20&include_entities=true&callback=?';
	$.getJSON(url, function(data) {
		appo = '<div class="contenitore"> <a href="
http://www.twitter.com/
' + profilo + '/">' + profilo + '</a>';
		$.each(data, function(i, item) {
			if (item.entities.media !== undefined) {
				for (var i=0, foto; foto = item.entities.media[i++];) {
					appo += '<div class="blocco"><a href="' + foto.media_url + '"> <img width="120" src="' + foto.media_url + '"/> </a><br><br>' + item.text + '</div>';
				};
			};
			appo += '</div> <br>';
			$('#tweets').append(appo);
		});
 
	});
};


 
 
Se non avessi voluto visualizzare il link al profilo nel container, non
avresti avuto neanche bisogno di questo, potevi creare tutto da
`renderTweets`.
 
Un'altra cosa. Noterai come ho rimosso tutti i <br>. Non ne hai bisogno.
Puoi tranquillamente mettere quanto spazio vuoi tra gli elementi
definendo regole CSS. In pratica tu generavi:
 
    <div class="blocco">
        <a href="...">
            <img src="..." />
        </a>
        <br>
        <br>
        Item Text
    </div>
 
Ma puoi avere tranquillamente:
 
    <div class="blocco">
        <a href="...">
            <img src="..." />
        </a>
        Item Text
    </div>
 
Impostando un `margin-bottom` per gli elementi "div.blocco > a".

Devo studiarmi bene quello che dici.
Io sono arrivato a questo e sembra funzionare bene, ma voglio capire bene quello che scrivi, perché mi hai già aperto svariati mondi che non conoscevo.
 
var url = '';
var appo = '';
var profilo = '';
html ='';
var contenitore = ['Leolabell', 'OfficialAsRoma'];
 
 
 
for (var a=0, profilo; profilo = contenitore[a++];) {
	url = '
https://api.twitter.com/1/statuses/user_timeline.json?screen_name=
' + profilo + '&count=100&include_entities=true&callback=?';
	$.getJSON(url, function(data) {
		$.each(data, function(i, item) {
			html = '<div class="contenitore"> <a href="
http://www.twitter.com/
' + 
item.user.name
 + '/">' + 
item.user.name
 + '</a>';
			if (item.entities.media !== undefined) {
				for (var i=0, foto; foto = item.entities.media[i++];) {
					appo += '<div class="blocco"><a href="' + foto.media_url + '"> <img width="120" src="' + foto.media_url + '"/> </a><br><br>' + item.text + '</div>';
				};
			};
		});
		html = html + appo + '</div> <br>';
		$('#tweets').append(html);
 
	});
};

Per me le Api di twitter sono una follia. Sto cercando di creare una pagina che mostri le foto degli amici di una specifico utente twitter. Ma ancora una volta mi restituisce un errore.
 
Sto cercando di usare la logica delle funzioni, ma quando chiamo:
https://api.twitter.com/1/friends/ids.json?cursor=-1&screen_name=grostein
 
 
Mi da come errore:
XMLHttpRequest cannot load 
https://api.twitter.com/1/friends/ids.json?cursor=-1&screen_name=grostein
. Origin null is not allowed by Access-Control-Allow-Origin.
 
dentro la documentazione non c'è niente. Il codice è:
 
 
function getfromuser(username)  {
	var contenitore = [];
	var appourl = '
https://api.twitter.com/1/friends/ids.json?cursor=-1&screen_name=
' + username;
	$.getJSON(appourl, function(data) {	
		$.each(data, function(i, item) {
			if (item.ids !== undefined) {
				for (var i=0, elemento; elemento = item.ids[i++];) {
					contenitore[i]=item;
				};
			};
		});
	});
	getid(contenitore);
};
 
 
 
function renderdata(url) {
	var appo = '';
	var profilo = '';
	html ='';
 
	$.getJSON(url, function(data) {	
		$.each(data, function(i, item) {
			html = '<div class="contenitore"> <a href="
http://www.twitter.com/
' + 
item.user.name
 + '/">' + 
item.user.name
 + '</a>';
			if (item.entities.media !== undefined) {
				for (var i=0, foto; foto = item.entities.media[i++];) {
					appo += '<div class="blocco"><a href="' + foto.media_url + '"> <img width="120" src="' + foto.media_url + '"/> </a><br><br>' + item.text + '</div>';
				};
			};
		});
	html = html + appo + '</div> <br>';
	$('#tweets').append(html);
	});
};
 
function getid(IDS) {
	var Timeline = '';
	for (var a=0, profilo; profilo = IDS[a++];) {
		Timeline = '
https://api.twitter.com/1/statuses/user_timeline.json?user_id=
' + profilo + '&count=200&include_entities=true&callback=?';
		renderdata(Timeline);
	};
 
};
 
 
 
$(document).ready(function() {
	getfromuser('OfficialAsRoma');
});
 


 
Ora, nei browser moderni è possibile fare richieste cross domain, se il
dominio che s'interroga (nel tuo caso `
api.twitter.com
`) lo consente.
Questo avviene tramite l'uso di specifici http header. Nel caso da te
descritto, e in quello che abbiamo già affrontato in precedenza, tali
header sono mancanti o malformati. Per questo il browser non è in grado
di ottemperare alla richiesta.

 XMLHttpRequest cannot load 
https://api.twitter.com/1/friends/ids.json?cursor=-1&screen_name=grostein
. Origin null is not allowed by Access-Control-Allow-Origin.
 


D'accordo, ma sono abituato in Python (sempre scarsissimo) e Javascript/Query ha delle complicazioni a cui non sono abituato. Un passo alla volta imparo anche questo.