Sending data from server to client not working properly - angularjs

I'm tying to send the last insert id from express to angularjs in my meanjs application.
When I check the id in server side it's returning properly. But in client side I'm not getting it the same way. For eg: say if the Id is 5527d2ed7ab73f7e412117c9, in angular what I'm getting is this:
Resource {0: "5", 1: "5", 2: "2", 3: "7", 4: "d", 5: "2", 6: "e", 7: "d", 8: "7", 9: "a", 10: "b", 11: "7", 12: "3", 13: "f", 14: "7", 15: "e", 16: "4", 17: "1", 18: "2", 19: "1", 20: "1", 21: "7", 22: "c", 23: "9", $promise: undefined, $resolved: true, $get: function, $save: function, $query: function…}0: "5"1: "5"2: "2"3: "7"4: "d"5: "2"6: "e"7: "d"8: "7"9: "a"10: "b"11: "7"12: "3"13: "f"14: "7"15: "e"16: "4"17: "1"18: "2"19: "1"20: "1"21: "7"22: "c"23: "9"$promise: undefined$resolved: true
My code is
Server code
exports.save(function (err, result) {
if (err) {
return res.send(400, err);
}
console.log(result._id);
res.jsonp(result._id);
});
Client code
$scope.$save(function (response) {
console.log(response)
}, onError);

Try returning an object instead, as result._id is a string and resource is expecting an object.
res.jsonp({id : result._id});
console.log(response.id)

Related

I am using ngFor on Array of objects and in html the data is not displaying

I am new to angular and stuff.
Below is the format of the array which is I am getting in the console.
[]
0: {_id: "5b90fb38345c932d46e61dae", name: "Andhra Pradesh", abbvr: "AP"}
1: {_id: "5b90fb38345c932d46e61daf", name: "Arunachal Pradesh", abbvr: "AR"}
2: {_id: "5b90fb38345c932d46e61db1", name: "Bihar", abbvr: "BR"}
3: {_id: "5b90fb38345c932d46e61db6", name: "Gujarat", abbvr: "GJ"}
4: {_id: "5b90fb38345c932d46e61db3", name: "Chhattisgarh", abbvr: "CG"}
5: {_id: "5b90fb38345c932d46e61db8", name: "Himachal Pradesh", abbvr: "HP"}
6: {_id: "5b90fb38345c932d46e61dbb", name: "Karnataka", abbvr: "KA"}
7: {_id: "5b90fb38345c932d46e61dbd", name: "Madhya Pradesh", abbvr: "MP"}
8: {_id: "5b90fb38345c932d46e61dc0", name: "Odisha", abbvr: "OR"}
9: {_id: "5b90fb38345c932d46e61dc2", name: "Punjab", abbvr: "PB"}
10: {_id: "5b90fb38345c932d46e61dc5", name: "Tamil Nadu", abbvr: "TN"}
11: {_id: "5b90fb38345c932d46e61dc7", name: "Tripura", abbvr: "TR"}
12: {_id: "5b90fb38345c932d46e61dca", name: "West Bengal", abbvr: "WB"}
13: {_id: "5b90fb38345c932d46e61db2", name: "Chandigarh", abbvr: "CD"}
14: {_id: "5b90fb38345c932d46e61dcc", name: "Andaman and Nicobar Islands", abbvr: "AN"}
15: {_id: "5b90fb38345c932d46e61db7", name: "Haryana", abbvr: "HR"}
16: {_id: "5b90fb38345c932d46e61dbc", name: "Kerala", abbvr: "KL"}
17: {_id: "5b90fb38345c932d46e61dc1", name: "Puducherry", abbvr: "PY"}
18: {_id: "5b90fb38345c932d46e61dc6", name: "Telangana", abbvr: "TL"}
19: {_id: "5b90fb38345c932d46e61dcb", name: "Manipur", abbvr: "MN"}
20: {_id: "5b90fb38345c932d46e61db0", name: "Assam", abbvr: "AS"}
21: {_id: "5b90fb38345c932d46e61db4", name: "Delhi", abbvr: "DL"}
22: {_id: "5b90fb38345c932d46e61db9", name: "Jammu and Kashmir", abbvr: "JK"}
23: {_id: "5b90fb38345c932d46e61db5", name: "Goa", abbvr: "GA"}
24: {_id: "5b90fb38345c932d46e61dbe", name: "Maharashtra", abbvr: "MH"}
25: {_id: "5b90fb38345c932d46e61dc3", name: "Rajasthan", abbvr: "RJ"}
26: {_id: "5b90fb38345c932d46e61dba", name: "Jharkhand", abbvr: "JH"}
27: {_id: "5b90fb38345c932d46e61dbf", name: "Meghalaya", abbvr: "ML"}
28: {_id: "5b90fb38345c932d46e61dc8", name: "Uttar Pradesh", abbvr: "UP"}
29: {_id: "5b90fb38345c932d46e61dcd", name: "Mizoram", abbvr: "MZ"}
30: {_id: "5b90fb38345c932d46e61dc4", name: "Sikkim", abbvr: "SK"}
31: {_id: "5b90fb38345c932d46e61dc9", name: "Uttarakhand", abbvr: "UK"}
32: {_id: "5b90fb38345c932d46e61dce", name: "Nagaland", abbvr: "NL"}
and HTML for the ngFor is:
<option *ngFor="let state of states" [value]="state.name">{{state.name}}</option>
In display there is number of option but nothing is visible when i am printing in console it shows undefined
Edit 1:
Below is the code of components which uses service
import { Component, OnInit } from '#angular/core';
import {VenueService} from './venue.service';
#Component({
selector: 'app-workshop',
templateUrl: './workshop.component.html',
styleUrls: ['./workshop.component.css']
})
export class WorkshopComponent {
states=[];
constructor(private venueService: VenueService) {
}
ngOnInit(){
this.venueService.getStates().subscribe(state => {
state.forEach(entry=>{
this.states.push(entry);
});
});
console.log(this.states);
}
}
Edit 2: I am Using Observable during api call and Interface,
so this would be my service method looks like:
getStates(): Observable<State[]>{
return http.get<State[]>('http://localhost:3000/api/getstate');
}
It should show an empty array because you have an async method if you want to display a array after the method you must use aysnc /wait or asyn pip in html:
async ngOnInit()
{ const states= await
this.venueService.getStates().toPromise();
console.log(states);
}
<option *ngFor="let state of states" [value]="state.name">{{state.name}}</option>
For second way:
it already mentioned in first Answer
If you can use the Observable directly from your service, as your example suggests, then the answer by Joseph Webber gets my vote.
However, if you want to perform some processing on the result first, then you can notify angular to detect your change, by calling detectChanges on the component's change detector.
For example:
import { Component, OnInit, ChangeDetectorRef } from '#angular/core';
import { VenueService } from './venue.service';
#Component({
selector: 'app-workshop',
templateUrl: './workshop.component.html',
styleUrls: ['./workshop.component.css']
})
export class WorkshopComponent implements OnInit {
states = [];
constructor(private venueService: VenueService,
private changeDetector: ChangeDetectorRef) {
}
ngOnInit() {
this.venueService.getStates().subscribe(state => {
// Do some stuff with the results ...
state.forEach(entry => {
this.states.push(entry);
});
// Let angular know.
this.changeDetector.detectChanges();
});
console.log(this.states);
}
}
Try like this,
<option *ngFor="let state of states" [ngValue]="state">{{state.name}}</option>
venueService.getStates() is asynchronous function.
Try below.
ngOnInit(){
this.venueService.getStates()
.subscribe(state => {
state.forEach(entry=>{
this.states.push(entry);
});
console.log(this.states);
});
}
Use the async pipe in your HTML and set states to the observable returned from your service.
<option *ngFor="let state of states | async" [value]="state.name">{{state.name}}</option>
ngOnInit(){
this.states = this.venueService.getStates();
}

AngularJS, Nested array

I have a problem with ng-repeat in AngularJs. I have an array of Objects with 3 different keys and one of those keys is an array of objects. So I simply use the ng-repeat for main array like this:
<div class="post-content" ng-repeat="post in nfc.posts track by $index">
...
</div>
Everything is ok. But when I use a nested ng-repeat in this loop, I get nothing. I used before nested ng-repeats a lot and faced no problem. Here is the code:
comments:: {{post.comments}}
<div class="post-comment" ng-repeat="comment in post.comments">
comment: {{comment}}
<img src="{{comment[3]}}" alt="" class="profile-photo-sm" />
<p>
{{comment[4] + ' ' + comment[5]}} {{comment[6]}}
</p>
</div>
The comments:: {{post.comments}} statement shows me the content, but the ng-repeat does not appear to work correctly.
A sample of comments object in browser console is here
Array(3)
0: {
0: 10196,
1: 10325,
2: 62,
3: 0,
4: Sun Feb 18 2018 21: 56: 58 GMT + 0330(+0330),
5: "text",
6: "text",
7: "text",
8: "text",
9: "text",
$$hashKey: "object:96"
}
1: {
0: 10195,
1: 10325,
2: 50,
3: 0,
4: Sun Feb 18 2018 20: 15: 41 GMT + 0330(+0330),
5: "text",
6: "text",
7: "text",
8: "text",
9: "text",
$$hashKey: "object:97"
}
2: {
0: 10194,
1: 10325,
2: 62,
3: 0,
4: Sat Feb 17 2018 12: 36: 39 GMT + 0330(+0330),
5: "text",
6: "text",
7: "text",
8: "text",
9: "text",
$$hashKey: "object:98"
}
This array is Array of arrays and I convert it to Array of objects after I receive it from API.
Where is my mistake?
First mistake I noticed in your code is this totoObject(itm["arrays"]))
$scope.posts.forEach(itm => (itm["comments"] = totoObject(itm["arrays"])));
your code that you provided in plunker says
function toObject(arr) {
var rv = {};
for (var i = 0; i < arr.length; ++i) rv[i] = arr[i];
return rv;
}
change totoObject to toObject
$scope.posts.forEach(itm => (itm["comments"] = toObject(itm["arrays"])));
Try
<img src="{{comment['3']}}" alt="" class="profile-photo-sm" />
comment[3] means that comment is an array and you are trying to access 4th element. Similarly change other uses as well.
Update 1
Check this plunkr. Below were your issues:
Use of totoObject
In your question you have provided array of objects (below code), which isn't the case in your plunkr. So, comment[3] would work just fine.
here (it shows array of objects)
0: {
0: 10196,
1: 10325,
2: 62,
3: 0,
4: Sun Feb 18 2018 21: 56: 58 GMT + 0330(+0330),
5: "text",
6: "text",
7: "text",
8: "text",
9: "text",
$$hashKey: "object:96"
}
Check the demo,
DEMO
var app =angular.module('testApp',[]);
app.controller('testCtrl',function($scope){
$scope.nfc ={};
$scope.nfc.posts = [
{
"Post": {
"Name": "text",
"Family": "text",
"UserName": "text",
"WorkPlace": "text",
"UserImage": "~/Images/User/Thumb1337305170mmkhalilzadeh2018294642.jpg",
"PPic": "~/Images/Post/1337305170502018211044.jpg",
"DSC": "text",
"CF": "text",
"CN": "(Mediastinum)",
"Rate": 0,
"MentionPostID": 0,
"FollowCount": 1,
"UserID": 50,
"Enable": 1,
"UPID": 10325,
"IsFollow": false,
"IsRate": false,
"IsFollowUser": true,
"RegDate": "2018-02-10T21:30:44.000Z"
},
"PostComment": [
[
10196,
10325,
62,
0,
"2018-02-18T18:26:58.000Z",
"text",
"~/Images/User/Thumb1337305170Shahryar201711122149.jpg",
"text",
"text",
"text"
],
[
10195,
10325,
50,
0,
"2018-02-18T16:45:41.000Z",
"text",
"~/Images/User/Thumb1337305170mmkhalilzadeh2018294642.jpg",
"text",
"text",
"text"
],
[
10194,
10325,
62,
0,
"2018-02-17T09:06:39.000Z",
"text",
"~/Images/User/Thumb1337305170Shahryar201711122149.jpg",
"text",
"text",
"text"
]
],
"newCommentText": "",
"comments": [
{
"0": 10196,
"1": 10325,
"2": 62,
"3": 0,
"4": "2018-02-18T18:26:58.000Z",
"5": "text",
"6": "~/Images/User/Thumb1337305170Shahryar201711122149.jpg",
"7": "text",
"8": "text",
"9": "text"
},
{
"0": 10195,
"1": 10325,
"2": 50,
"3": 0,
"4": "2018-02-18T16:45:41.000Z",
"5": "text",
"6": "~/Images/User/Thumb1337305170mmkhalilzadeh2018294642.jpg",
"7": "text",
"8": "text",
"9": "text"
},
{
"0": 10194,
"1": 10325,
"2": 62,
"3": 0,
"4": "2018-02-17T09:06:39.000Z",
"5": "text",
"6": "~/Images/User/Thumb1337305170Shahryar201711122149.jpg",
"7": "ttt",
"8": "ttt",
"9": "ttt"
}
]
}
];
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="testApp" ng-controller="testCtrl">
<div class="post-content" ng-repeat="post in nfc.posts track by $index">
<div class="post-comment" ng-repeat="comment in post.comments">
<img src="{{comment[3]}}" alt="" class="profile-photo-sm" />
<p>
{{comment[4] + ' ' + comment[5]}} {{comment[6]}}
</p>
</div>
</div>
</body>

Getting elements from array of dictionary and save the keys as string, and values as string

I have an array of dictionaries of type <Int,String> like this:
[14: "2", 17: "5", 6: "5", 12: "Ali", 11: "0", 2: "4", 5: "It it it", 15: "5", 18: "2", 16: "5", 8: "2", 13: "4", 19: "4", 1: "2", 4: "12-09-2017 - 9:52"]
I need to get the keys alone and save them in a string, and the values alone and save them in another string.
The results should look like that:
string key = "12,17,6,12,11,2,5,15,18,16,8,13,19,1,4"
string values = "2,5,5,Ali,0,4,It it ti,5,2,5,2,4,4,2,12-09-2017 - 9:52"
A dictionary has a keys and a values property which return the
keys/values as a (lazy) collection. For the values you just have
to join them:
let dict = [14: "2", 17: "5", 6: "5", 12: "Ali", 11: "0", 2: "4", 5: "It it it", 15: "5", 18: "2", 16: "5", 8: "2", 13: "4", 19: "4", 1: "2", 4: "12-09-2017 - 9:52"]
let values = dict.values.joined(separator: ",")
// Ali,5,2,It it it,5,0,4,5,4,4,2,12-09-2017 - 9:52,5,2,2
The keys are integers and must be converted to strings first:
let keys = dict.keys.map(String.init).joined(separator: ",")
// 12,17,14,5,15,11,13,16,19,2,18,4,6,8,1
The order is unspecified, but the same for keys and values.
Try this, this can be refactored I am sure, this is the first logic that hit me.
let dictionary = [14: "2", 17: "5", 6: "5", 12: "Ali", 11: "0", 2: "4", 5: "It it it", 15: "5", 18: "2", 16: "5", 8: "2", 13: "4", 19: "4", 1: "2", 4: "12-09-2017 - 9:52"]
let arrayKeys = dictionary.map({ $0.key})
print(arrayKeys)
var stringValue: String = ""
for value in arrayKeys {
stringValue.append(value.description)
stringValue.append(",")
}

$http get returns different than $resource get

I am trying to download user reports using a User $resource. However, the returned result comes in an object like so: (weird)
{0: "n", 1: "a", 2: "m", 3: "e", 4: ",", 5: "e", 6: "m", 7: "a", 8: "i", 9: "l", 10: ",", 11: "p", 12: "a", 13: "r", 14: "t", 15: "n", 16: "e", 17: "r", 18: ",", 19: "r", 20: "o", 21: "l", 22: "e", 23: ",", 24: "p", 25: "h", 26: "o", 27: "n", 28: "e", 29: ",", 30: "s", 31: "t", 32: "a", 33: "t", 34: "u", 35: "s", 36: "↵", 37: "M", 38: "i", 39: "c", 40: "h", 41: "a", 42: "e", 43: "l", 44: " ", 45: "J", 46: "o", 47: "r", 48: "d", 49: "a", 50: "n", 51: ",", 52: "m", 53: "j", 54: "#", 55: "m", 56: "j", 57: ".", 58: "c", 59: "o", 60: "m", 61: ",", 62: ",", 63: "a", 64: "d", 65: "m", 66: "i", 67: "n", 68: ",", 69: "8", 70: "0", 71: "1", 72: "5", 73: "6", 74: "4", 75: "1", 76: "3", 77: "6", 78: "1", 79: ",", 80: "↵", $promise: Promise, $resolved: true}
When I use $http.get everything comes as expected:
name,email,partner,role,phone,status
Michael Jordan,mj#mj.com,,admin,8015641361,
I have no idea what I am doing wrong. Here are my files:
search.controller.js (with two approaches producing different results)
$scope.downloadReport = function() {
$http.get('/api/users/download',{params:$state.params}).success(function(res) {
console.log(res)
var anchor = angular.element('<a/>');
anchor.attr({
href: 'data:attachment/csv;charset=utf-8,' + encodeURI(res),
target: '_blank',
download: 'filename.csv'
})[0].click();
});
User.download($state.params,function(res){
console.log(res)
var anchor = angular.element('<a/>');
anchor.attr({
href: 'data:attachment/csv;charset=utf-8,' + encodeURI(res),
target: '_blank',
download: 'Users.csv'
})[0].click();
},function(err){
console.log(err)
});
};
user.service.js (tried with and without isArray)
angular.module('Raizzle.Admin')
.factory('User', function ($resource) {
return $resource('/api/users/:id/:controller', { id: '#_id'}, {
download: {
method: 'GET',
params: {
id:'download'
}
},
changePassword: {
method: 'PUT',
params: {
controller:'password'
}
},
get: {
method: 'GET',
params: {
id:'me'
}
}
});
});
I'm guessing that $resource has a hard time returning raw data? Any ideas?
Thanks in advance!
$resource assumes the response is a JSON object and does additional processing under that assumption. You have several options here to solve your problem:
Use transformResponse to avoid parsing to JSON object (see $resource documentation about transformResponse: https://docs.angularjs.org/api/ngResource/service/$resource ), not sure that would even work.
Use $http instead of $resource.
Make the backend return a JSON object instead of plaintext.
if you use $resource, transformResponse it must be something like:
{ ...
method: "GET",
transformResponse: function(data, headersGetter, status) {
return {content: data};
}
in GET of user.service.js

Why I get empty POST in server from Angular JS?

I have array in Angular JS:
$scope.formData.conditions
Before AJAX request I display this varaible:
[1: "1", 2: "2", 3: "3", 4: "4", 5: "5"]
But on server PHP I get array like as:
["conditions"]=>
array(6) {
[0]=>
string(0) ""
[1]=>
string(1) "1"
[2]=>
string(0) ""
[3]=>
string(1) "3"
[4]=>
string(1) "4"
[5]=>
string(1) "5"
}
Why element with index 2 is empty?
Because that's not an array, that's an object. Server-side you then convert it to an array. This conversion process is the problem. Send it as a dictionary ({1: "1", 2: "2", 3: "3", 4: "4", 5: "5"}) and PHP will know to convert it into a sparse array (which is a dictionary too).

Resources