Estou procurando desenvolver localmente com apenas um arquivo JSON codificado. Meu arquivo JSON é o seguinte (válido quando colocado no validador JSON):
{
"contentItem": [
{
"contentID" : "1",
"contentVideo" : "file.mov",
"contentThumbnail" : "url.jpg",
"contentRating" : "5",
"contentTitle" : "Guitar Lessons",
"username" : "Username",
"realname" : "Real name",
"contentTags" : [
{ "tag" : "Guitar"},
{ "tag" : "Intermediate"},
{ "tag" : "Chords"}
],
"contentAbout" : "Learn how to play guitar!",
"contentTime" : [
{ "" : "", "" : "", "" : "", "" : ""},
{ "" : "", "" : "", "" : "", "" : ""}
],
"series" :[
{ "seriesVideo" : "file.mov", "seriesThumbnail" : "url.jpg", "seriesTime" : "time", "seriesNumber" : "1", "seriesTitle" : "How to Play Guitar" },
{ "videoFile" : "file.mov", "seriesThumbnail" : "url.jpg", "seriesTime" : "time", "seriesNumber" : "2", "seriesTitle" : "How to Play Guitar" }
]
},{
"contentID" : "2",
"contentVideo" : "file.mov",
"contentThumbnail" : "url.jpg",
"contentRating" : "5",
"contentTitle" : "Guitar Lessons",
"username" : "Username",
"realname" : "Real name",
"contentTags" : [
{ "tag" : "Guitar"},
{ "tag" : "Intermediate"},
{ "tag" : "Chords"}
],
"contentAbout" : "Learn how to play guitar!",
"contentTime" : [
{ "" : "", "" : "", "" : "", "" : ""},
{ "" : "", "" : "", "" : "", "" : ""}
],
"series" :[
{ "seriesVideo" : "file.mov", "seriesThumbnail" : "url.jpg", "seriesTime" : "time", "seriesNumber" : "1", "seriesTitle" : "How to Play Guitar" },
{ "videoFile" : "file.mov", "seriesThumbnail" : "url.jpg", "seriesTime" : "time", "seriesNumber" : "2", "seriesTitle" : "How to Play Guitar" }
]
}
]
}
Coloquei meu controlador, fábrica e html funcionando quando o JSON foi codificado dentro da fábrica. No entanto, agora que substituí o JSON pelo código $ http.get, ele não funciona. Já vi tantos exemplos diferentes de $ http e $ resource, mas não tenho certeza para onde ir. Estou procurando a solução mais simples. Estou apenas tentando obter dados para diretivas ng-repeat e semelhantes.
Fábrica:
theApp.factory('mainInfoFactory', function($http) {
var mainInfo = $http.get('content.json').success(function(response) {
return response.data;
});
var factory = {}; // define factory object
factory.getMainInfo = function() { // define method on factory object
return mainInfo; // returning data that was pulled in $http call
};
return factory; // returning factory to make it ready to be pulled by the controller
});
Toda e qualquer ajuda é apreciada. Obrigado!
Respostas:
Ok, aqui está uma lista de coisas a serem examinadas:
1) Se você não estiver executando um servidor da web de qualquer tipo e apenas testando com o arquivo: //index.html, provavelmente você está enfrentando problemas de política de mesma origem. Vejo:
https://code.google.com/archive/p/browsersec/wikis/Part2.wiki#Same-origin_policy
Muitos navegadores não permitem que arquivos hospedados localmente acessem outros arquivos hospedados localmente. O Firefox permite, mas apenas se o arquivo que você está carregando estiver na mesma pasta do arquivo html (ou em uma subpasta).
2) A função de sucesso retornada de $ http.get () já divide o objeto de resultado para você:
$http({method: 'GET', url: '/someUrl'}).success(function(data, status, headers, config) {
Portanto, é redundante chamar o sucesso com função (resposta) e retornar response.data.
3) A função de sucesso não retorna o resultado da função que você passou, então ela não faz o que você pensa:
var mainInfo = $http.get('content.json').success(function(response) { return response.data; });
Isso está mais próximo do que você pretendia:
var mainInfo = null; $http.get('content.json').success(function(data) { mainInfo = data; });
4) Mas o que você realmente deseja fazer é retornar uma referência a um objeto com uma propriedade que será preenchida quando os dados forem carregados, algo assim:
theApp.factory('mainInfo', function($http) { var obj = {content:null}; $http.get('content.json').success(function(data) { // you can do some processing here obj.content = data; }); return obj; });
mainInfo.content iniciará como nulo e, quando os dados forem carregados, ele apontará para eles.
Como alternativa, você pode retornar a promessa real que $ http.get retorna e usar:
theApp.factory('mainInfo', function($http) { return $http.get('content.json'); });
E então você pode usar o valor de forma assíncrona em cálculos em um controlador:
$scope.foo = "Hello World"; mainInfo.success(function(data) { $scope.foo = "Hello "+data.contentItem[0].username; });
fonte
Gostaria de observar que a quarta parte da Resposta Aceita está errada .
theApp.factory('mainInfo', function($http) { var obj = {content:null}; $http.get('content.json').success(function(data) { // you can do some processing here obj.content = data; }); return obj; });
O código acima, como escreveu @Karl Zilles, falhará porque
obj
sempre será retornado antes de receber os dados (portanto, o valor sempre seránull
) e isso ocorre porque estamos fazendo uma chamada assíncrona.Os detalhes de questões semelhantes são discutidos nesta postagem
No Angular, use
$promise
para lidar com os dados buscados quando quiser fazer uma chamada assíncrona.A versão mais simples é
theApp.factory('mainInfo', function($http) { return { get: function(){ $http.get('content.json'); // this will return a promise to controller } }); // and in controller mainInfo.get().then(function(response) { $scope.foo = response.data.contentItem; });
Não uso
success
eerror
acabei de descobrir no documento que esses dois métodos estão obsoletos.fonte
return $http.get('content.json');
na fábrica, caso contrário, o retorno é nulo..success
agora está obsoleto. Use em seu.then
lugar. docs.angularjs.org/api/ng/service/$httpesta resposta me ajudou muito e me indicou a direção certa, mas o que funcionou para mim, e espero que para outros, é:
menuApp.controller("dynamicMenuController", function($scope, $http) { $scope.appetizers= []; $http.get('config/menu.json').success(function(data) { console.log("success!"); $scope.appetizers = data.appetizers; console.log(data.appetizers); }); });
fonte
Eu tenho aproximadamente esses problemas. Preciso depurar o aplicativo AngularJs do Visual Studio 2013.
Por padrão, o IIS Express restringe o acesso a arquivos locais (como json).
Mas, primeiro: JSON tem sintaxe JavaScript.
Segundo: arquivos javascript são permitidos.
Então:
renomeie JSON para JS (
data.json->data.js
).comando de carregamento correto (
$http.get('App/data.js').success(function (data) {...
carregar script data.js para a página (
<script src="App/data.js"></script>
)Em seguida, use os dados carregados de maneira usual. É apenas uma solução alternativa, é claro.
fonte
++ Isso funcionou para mim. É
vanilla javascirpt
bom para casos de uso, como desordem ao testar com angMocks
biblioteca:<!-- specRunner.html - keep this at the top of your <script> asset loading so that it is available readily --> <!-- Frienly tip - have all JSON files in a json-data folder for keeping things organized--> <script src="json-data/findByIdResults.js" charset="utf-8"></script> <script src="json-data/movieResults.js" charset="utf-8"></script>
Este é o seu
javascript
arquivo que contém osJSON
dados// json-data/JSONFindByIdResults.js var JSONFindByIdResults = { "Title": "Star Wars", "Year": "1983", "Rated": "N/A", "Released": "01 May 1983", "Runtime": "N/A", "Genre": "Action, Adventure, Sci-Fi", "Director": "N/A", "Writer": "N/A", "Actors": "Harrison Ford, Alec Guinness, Mark Hamill, James Earl Jones", "Plot": "N/A", "Language": "English", "Country": "USA", "Awards": "N/A", "Poster": "N/A", "Metascore": "N/A", "imdbRating": "7.9", "imdbVotes": "342", "imdbID": "tt0251413", "Type": "game", "Response": "True" };
Por fim, trabalhe com os dados JSON em qualquer lugar do seu código
// working with JSON data in code var findByIdResults = window.JSONFindByIdResults;
Nota: - Isso é ótimo para teste e até
karma.conf.js
aceita esses arquivos para execução de testes, conforme mostrado abaixo. Além disso, eu recomendo isso apenas para organizar dados etesting/development
ambiente.// extract from karma.conf.js files: [ 'json-data/JSONSearchResultHardcodedData.js', 'json-data/JSONFindByIdResults.js' ... ]
Espero que isto ajude.
++ Baseado nesta resposta https://stackoverflow.com/a/24378510/4742733
ATUALIZAR
Uma maneira mais fácil que funcionou para mim é incluir um
function
na parte inferior do código retornando qualquer coisaJSON
.// within test code let movies = getMovieSearchJSON(); ..... ... ... .... // way down below in the code function getMovieSearchJSON() { return { "Title": "Bri Squared", "Year": "2011", "Rated": "N/A", "Released": "N/A", "Runtime": "N/A", "Genre": "Comedy", "Director": "Joy Gohring", "Writer": "Briana Lane", "Actors": "Brianne Davis, Briana Lane, Jorge Garcia, Gabriel Tigerman", "Plot": "N/A", "Language": "English", "Country": "USA", "Awards": "N/A", "Poster": "http://ia.media-imdb.com/images/M/MV5BMjEzNDUxMDI4OV5BMl5BanBnXkFtZTcwMjE2MzczNQ@@._V1_SX300.jpg", "Metascore": "N/A", "imdbRating": "8.2", "imdbVotes": "5", "imdbID": "tt1937109", "Type": "movie", "Response": "True" } }
fonte