I have recently learned AngularJS. I started a small project. I was able to extract data from a json file. My current task is to be able to extract data from multiple json files. How can I do this?
I made my first json file this way:
$http.get("personel.json")
.then(function(gelen) {
$scope.personeller = gelen.data;
});
I have 9 more json files that I need to take, but I want to see the data of the file I'm calling
$http.get("1.json")
.then(function(veri1) {
$scope.x1 = veri1.data;
});
the other files are named "1.json, 2.json, 3.json ....... 9.json"
How can I change the location of the 1.json in the top code block?I am sorry for my English.The first time I am writing to a foreign forum. Thanks in advance
$scope.getdetail = function(detail) {
$scope.result = detail;
$http.get($scope.result.id + ".json")
.then(function(veri1) {
$scope.x1 = veri1.data;
});
}
I solved my problem this way thanks.
You can wrap the $http call in a function and pass in the filename you wish to retrieve like this:
Edit I modifed the code here adding a promise to handle issues that could arise from asynchronous requests
$scope.getFile = async function(fileName){
return new Promise((res, err) => {
$http.get(fileName).then(function(result){
res(result.data);
})
})
}
$scope.file1 = $scope.getFile("1.json");
$scope.file2 = $scope.getFile("2.json");
$scope.file3 = $scope.getFile("3.json");
$scope.file4 = $scope.getFile("4.json");
$scope.file5 = $scope.getFile("5.json");
$scope.file6 = $scope.getFile("6.json");
$scope.file7 = $scope.getFile("7.json");
$scope.file8 = $scope.getFile("8.json");
$scope.file9 = $scope.getFile("9.json");
If the files are sequential and numeric you could also use this to pull all the data from the file into a single array using a for loop.
$scope.returnedFiles = [];
for(i = 0; i < 9; i++){
$scope.getFile(i + ".json").then(fileData => {
$scope.returnedFiles.push(fileData);
});
}
Related
I'm trying to use map function in my vue component. I have a file upload input that will accept multiple files. Since I'm working with electron, I can't pass directly the files to the backend of the app so I want to use the Array.prototype.map() function to get files path and proces them after passing the array using the ipcRenderer.send() function. Anyway I get always this error this.$refs.selectedImages.files.map is not a function how I can fix it?
Here is the actual code I'm trying
handleFiles() {
this.files = this.$refs.selectedImages.files.map( (file) => file.path ); //this will cause the error
}, //
processFiles() {
this.isLoading = true;
window.ipcRenderer.send('processFiles', this.files);
window.ipcRenderer.on('', (event, data) => {
console.log(ecent, data);
saveAs(data, 'processed.mfs')
});
}
UPDATE
To try solve the problem I'm looping the FilesList to extract the path of each file and then pass it using ipcRenderer. The problem is that I'm not able to get the message on the background.js and I'm not sure why.
this.$refs.selectedImages.files.forEach( (file) => {
this.files.push(file.path) // this will push into the array the path of each file
})
window.ipcRenderer.send('processFiles', this.files);
//background.js
import { ipcMain } from 'electron'
ipcMain.on('processFiles', (event, data) => {
console.log(event, data) // the message will not arrive
})
The FileList object is actually not an array, and has no .map method. But you can access the files like this:
const files = this.$refs.selectedImages.files;
for (var i = 0; i < files.length; i++) {
console.log(files[i]);
}
fetching data from axios response return undefined value when console.logged
I have tried numerous way but the response is always shows undefined
This is the usersdata
const userdatas=[ {id: 1,firstname: "Leanne",lastname:"Gram",password: "123",phone:"9474211442"}**
Client
handleSubmit=(e)=>{
alert(this.state.Firstname)
e.preventDefault();
axios.post('http://localhost:3001/login', {
lastname: JSON.stringify(this.state.Lastname),
firstname: JSON.stringify(this.state.Firstname),
password:JSON.stringify(this.state.password),
phoneno:JSON.stringify(this.state.phoneno)
}).then(res=>alert(res.data.id))
}
]
Express
const userdatas=[ {id: 1,firstname: "Leanne",lastname:"Gram",password: "123",phone:"9474211442"}**
app.post('/login',(req,res)=>{
let logindetail={firstname:req.body.firstname,
password:req.body.password}
logindetail.firstname=logindetail.firstname.replace(/['"]+/g, '')
logindetail.password=logindetail.password.replace(/['"]+/g, '')
var count = Object.keys(userdatas).length;
for(var i=0;i<count;i++)
{
if(logindetail.firstname===userdatas[i].firstname&&logindetail.password===userdatas[i].password)
{
res.json(userdatas[i])
}
}
});
In your Express section, userdatas appears to be an object, but you are trying to look it up like an array in your res.json call. You need to wrap it in Object.keys like you have when you are setting your count value.
Seeing as what you receive on the backend doesn’t appear to be right , I’d revisit the frontend request. IMHO, you ought to only have one JSON.stringify call against the whole object you want to wrap, not a separate call per prop. Try that and then see what the backend receives.
First the userdatas is an object and you are trying to access its values as in an array. Secondly are you sure that the if condition inside the loop gets satisfied once?. Because you can't have multiple responses to a single request. Build a single response body in a variable as you loop. Send it once the loop is finished.
for (var i = 0; i < count; i++) {
if (
logindetail.firstname === userdatas[i].firstname &&
logindetail.password === userdatas[i].password
) {
res.json(userdatas[i]);
}
}
Change it to something like this
let result = [];
for (var i = 0; i < count; i++) {
if (***your corrected condition***) {
result = userdatas[i];
}
}
res.send(result);
What I'm working with
angular2
firebase
What I have
A returned object
Each item in the object has a URL property
What I would like to do
Loop through each of the items in the object and get the URL property
Pass that into a firebase storage variable
Push the URL property into an array to make available for my HTML
note: I have this working by hard coding a url, I just need some assistance looping through the object to get the other urls in the object.
Component.ts
'this.imagesToDisplay' will return an object of object (image below)
this.activatedRoute.data
.subscribe((
data: { issueData: any, issueImageData: any }) => {
this.issueToDisplay = data.issueData;
this.imagesToDisplay = data.issueImageData;
this.testing(this.imageToDisplayArray);
});
Comnponent TS - Testing method
So this is hardcoded and pushes the hardcoded url into the array and displays correctly through databinding with the HTML. Cool. However, I would like to loop through the 'imagesToDisplay' object and get both returned urls.
testing(imageToDisplayArray) {
// this works with one url
var storage = firebase.storage().ref().child("image/-Kosd82P-bmh4SFetuf3/-Kosd8HhGmFiUhYMrlvw/30DD9F39-4684-4AA0-9DBF-3B0F0C3450A4.jpg");
storage.getDownloadURL().then(function(url) {
imageToDisplayArray.push(url);
console.log(imageToDisplayArray);
});
}
Any help here would be massively appreciated.
Note: I think this question here is what I'm trying to do, I'm just not sure how to integrate that into my current code. Any help would be awesome.
Stack Overflow question on firebase storage looping
UPDATE
So, I'm incredibly close now. I just have one issue. The code below loops through the returned data and extract the URL properties. I use the url properties to connect to the firebase storage and return the download URLs. Both of these are logged to the console! Awesome. I now have the URLs i needed! The issue I'm having is, it will only let me push these values to a local array. In this instance 'var array'. I need to push to an array that's outside of the 'activatedRoute' 'method'. Anytime I do, it returns as undefined.
this.activatedRoute.data
.subscribe((
data: { issueData: any, issueImageData: any }) => {
this.issueToDisplay = data.issueData;
this.imagesToDisplay = data.issueImageData;
var array = [];
data.issueImageData.forEach(image => {
// Reference to the image URL
var image = image.url;
// Firebase storage
var storage = firebase.storage();
// Path reference
var imagePathReference = storage.ref().child(image);
// Get Download URL
imagePathReference.getDownloadURL().then(function (url) {
console.log(url);
array.push(url);
})
});
});
I would recommend you to use the features rxjs provides you:
this.activatedRoute.data.switchMap(data => {
let parsedData = {
issueToDisplay: data.issueData,
imagesToDisplay: data.issueImageData
}
let imageUrls$ = data.issueImageData.map(image => {
var imagePathReference = storage.ref().child(image);
return Observable.fromPromise(imagePathReference.getDownloadURL())
});
return Observable.forkJoin(imageUrls$).map((...urls) => {
return Object.assign(parsedData, { urls });
})
}).subscribe(data => {
/*
data looks like this:
{
issueToDisplay: any,
imagesToDisplay: any,
urls: string[]
}
*/
});
If I'm correct, you're looking for a solution to map an array-like object of objects to an actual array of objects.
Here is a way to do just that:
var object = {
'0': {
"url": "url1",
"name": "obj1",
"data": 1234
},
'1': {
"url": "url2",
"name": "obj2",
"data": 5678
},
'length': 2
}
var sliced = Array.prototype.slice.call( object, 0 );
console.log(sliced)
Couple remarks:
If you wonder how this works, check this post.
Alternative syntax that you could encounter looks like [].slice.call()
If you want to perform array-like operations, you can probably do that right away with Array.prototype.<METHOD>.call(object, <CALLBACK>
For example:
Array.prototype.map.call(object, function(el) { // return your enhanced element })
So, this works. Not entirely sure how clean it is. But it works.
this.activatedRoute.data
.subscribe((
data: { issueData: any, issueImageData: any }) => {
this.issueToDisplay = data.issueData;
this.imagesToDisplay = data.issueImageData;
var localImageArray = [];
data.issueImageData.forEach(image => {
// Reference to the image URL
var image = image.url;
// Firebase storage
var storage = firebase.storage();
// Path reference
var imagePathReference = storage.ref().child(image);
// Get Download URL
imagePathReference.getDownloadURL().then(function (url) {
localImageArray.push(url);
})
this.getIssueImageArray(localImageArray);
});
});
}
// Get Image Array
getIssueImageArray(array) {
this.imageToDisplayArray = array;
}
I made a for loop and inside I make a $http call to my API.
The for loop makes the calls in a specific order, but how I get the reponse is totally messed up..
This is my code:
for (var i = 0; i < amountOfEntries; i++) {
var _imageId = NieuwsService.nieuws[i].image;
if (_imageId != "") {
var uriString = "Web/Lists/getbytitle('Afbeeldingen%20voor%20nieuwsberichten')/Items(" + _imageId + ")/File";
NieuwsService.createRequest(requestUrl, baseUrl, uriString).then(function (response) {
var _parser = new DOMParser();
var _xmlData = _parser.parseFromString(response.data, "text/xml");
var _entry = _xmlData.getElementsByTagName("entry");
var _imageUrl = "http://sharepoint" + _entry[0].getElementsByTagNameNS("*", "ServerRelativeUrl")[0].childNodes[0].nodeValue;
//Display
$('#imageList').append("<li><a href='#'>" + _imageUrl + "</a></li>");
NieuwsService.images.push(_imageUrl);
})
}
}
var _createRequest = function (requestUrl, baseUrl, uriString) {
var promise = $http.get(requestUrl, {
params: {
"baseUrl": baseUrl,
"uriString": uriString
}
})
return promise;
}
NieuwsService.createRequest = _createRequest;
return NieuwsService;
So the question is, how do I get the responses in the order I make the calls?
You can create and array of promises, then use $q.all that will resolve when all the requests are done, and you will have the result of each one in the same position where you added the promise.
$http is ASYNC by design, it means that each HTTP will go out in the same order but the response depends on many cases (network,dns, server response time ext...)
you should design your code in a way that it will take that into consideration.
You can use promise
As #RonnieTroj pointed out, the ajax calls are asynchronous and there is no defined order in that respect.
However, if you want to chain api calls such that you get responses in a specific order, then your only option is nesting calls in the following way:
call1.then(function(data1) { //first call
call2.then(function(data2) {//second call after first call completes
//and so on
})
})
However, the issue with this method is that it will take more time because you are essentially making the calls sequential in nature(one call executes, then another instead of parallel async calls.)
I need to download a file from the server. The file is stored in the database. I have a cs controller that serves a file back to UI. The server GET call looks like this:
http://server/api/controllername/fileid/data
It does work when I run that link in the Browser - the file comes down and goes into the download area (Chrome). But when I send the same command from my Angualar code I dont see any file. The console reports that my request was successful (code 200), but I just dont see anything. Please let me know what code fragments to post to make it easier to help.
Thanks
Create a link to the resource, and don't handle it with ajax.
If you make the link open in a new tab, the tab will automatically close after it realises it was just opened to download a file in most modern browsers.
Try this code:
var a = document.createElement('a');
a.href = "http://server/api/controllername/fileid/data";
a.click();
You can compose the address concatenating variables and text.
The file probably downloads correctly as a byte[] to the calling it but that would be useless to the user - as was my problem.
In my case I needed to download a file with a complex set of parameters. This example JavaScript uses a post request and creates a form (and posts it) with any JavaScript object that you give it. This code may help if you simplified it:
private open(verb, url, data, target)
{
var form = document.createElement("form");
form.action = url;
form.method = verb;
form.target = target || "_self";
if (data) {
this.createFormParameters(form, "", data);
}
form.style.display = 'none';
document.body.appendChild(form);
form.submit();
}
private createFormParameters(form, key, value) {
// recursive algorithm to add parameters (including objects and arrays of objects) to a custom form
if (typeof value === "object") {
for (var item in value) {
if (Array.isArray(value[item])) {
for (var arrayItem in value[item]) {
this.createFormParameters(form, (item + "[" + arrayItem + "]."), value[item][arrayItem]);
}
continue;
}
var input = document.createElement("textarea");
input.name = key + item;
input.value = value[item];
form.appendChild(input);
}
}
else
{
var input = document.createElement("textarea");
input.name = key;
input.value = value;
form.appendChild(input);
}
}