How can you reuse an object property in a loop in javascript? - javascript

I was trying to reuse an object property in a loop. Is this the right way? I'm always getting an undefined error. The properties I want to use are 'field_id' and 'field_text'. I'm not sure if it should be defined as a variable or a string.
Below is my full code:
var client_id = '', company_name = '', vacancy_category_id = '', category_name = '', user_id = '', full_name = '';
let select2El = {
params: [{
'id': '#client_id',
'url': '/consultant/vacancy/get-clients',
'field_id': client_id,
'field_text': company_name,
'success_response': $scope.clients
}, {
'id': '#clone_client_id',
'url': '/consultant/vacancy/get-clients',
'field_id': client_id,
'field_text': company_name,
'success_response': $scope.clients
}, {
'id': '#category_id',
'url': '/consultant/vacancy/get-categories',
'field_id': vacancy_category_id,
'field_text': category_name,
'success_response': $scope.categories
}, {
'id': '#owner_id',
'url': '/consultant/vacancy/get-users-by-type',
'field_id': user_id,
'field_text': full_name,
'success_response': $scope.users
}]
}
for (var key in select2El.params) {
var sel = select2El.params[key];
angular.element(sel['id']).select2({
width: '100%',
placeholder: '--Select--',
ajax: {
url: sel['url'],
dataType: 'json',
data: function (params) {
return {
search: params.term,
page: params.page || 1
}
},
processResults: function (response, params) {
params.page = params.page || 1;
return {
results: response.data.map(function (res) {
console.log(res);
return { id: res.sel['field_id'], 'text': res.sel['field_text'] }
}),
pagination: {
more: (params.page * 10) < response.total
}
};
},
success: function (response) {
sel['success_response'] = response.data;
}
}
});
}
The line where the object property has been looped over is this:
return { id: res.sel['field_id'], 'text': res.sel['field_text']
When I console.log(res), I get this data.

This is happening because your res.sel field is undefined. From what I understand you want the value field_id and field_text from the object stored in select2El.params.
Try the following code -
var client_id = '', company_name = '', vacancy_category_id = '', category_name = '', user_id = '', full_name = '';
let select2El = {
params: [{
'id': '#client_id',
'url': '/consultant/vacancy/get-clients',
'field_id': client_id,
'field_text': company_name,
'success_response': $scope.clients
}, {
'id': '#clone_client_id',
'url': '/consultant/vacancy/get-clients',
'field_id': client_id,
'field_text': company_name,
'success_response': $scope.clients
}, {
'id': '#category_id',
'url': '/consultant/vacancy/get-categories',
'field_id': vacancy_category_id,
'field_text': category_name,
'success_response': $scope.categories
}, {
'id': '#owner_id',
'url': '/consultant/vacancy/get-users-by-type',
'field_id': user_id,
'field_text': full_name,
'success_response': $scope.users
}]
}
for (let key in select2El.params) {
let sel = select2El.params[key];
angular.element(sel['id']).select2({
width: '100%',
placeholder: '--Select--',
ajax: {
url: sel['url'],
dataType: 'json',
data: function (params) {
return {
search: params.term,
page: params.page || 1
}
},
processResults: function (response, params) {
params.page = params.page || 1;
return {
results: response.data.map(function (res, index) {
console.log(res);
return { id: sel['field_id'], 'text': sel['field_text'] }
}),
pagination: {
more: (params.page * 10) < response.total
}
};
},
success: function (response) {
sel['success_response'] = response.data;
}
}
});
}
I used index inside .map to fetch the values of field_text and field_id from the original object

Related

replace url params with values of an object

I have a object like this:
let data = {
url: "https://test.ir/apps/:type/:id/",
params: {
id: "com.farsitel.bazaar",
type: "xyz",
},
query: {
ref: "direct",
l: "en",
},
};
I want to replace :type and :id in url with equivalent key to each from params object. what is the best solution in javascript?
Solution based on matching keys from params to the value of a regular expression from key url, followed by an update of that key.
On input: https://test.ir/apps/:type/:id/
On output: https://test.ir/apps/xyz/com.farsitel.bazaar/
let data = {
url: "https://test.ir/apps/:type/:id/",
params: {
id: "com.farsitel.bazaar",
type: "xyz",
},
query: {
ref: "direct",
l: "en",
},
};
let new_url = data.url.replace(/:(\w+)/g, (match, key) => data.params[key] || match);
data.url = new_url;
console.log(data);
Could you just use String.replace?
const data = {
url: "https://test.ir/apps/:type/:id/",
params: {
id: "com.farsitel.bazaar",
type: "xyz",
},
query: {
ref: "direct",
l: "en",
},
}
const url = data.url.replace(":type", data.params.type).replace(":id", data.params.id);
console.log(url)

how to get data updated data to show up in vue after fetching it

In order to load some data from the server after the page has loaded I have the following script:
<script>
export default {
data() {
return {
imageDirectory: "../../images/",
fileName: "img",
extension: ".png",
products:
[
{
name: 'loading data',
imageUrl: require("../../assets/t1.png")
}
]
}
},
name: "ProductList",
created: function () {
this.fetchData();
},
methods: {
fetchData: function () {
$.ajax({
type: "GET",
timeout: 1200000,
url: 'api/test',
contentType: "application/json",
dataType: "text",
success: function (data) {
window.alert(data);
this.products = [{
name: 'success' + 'test',
imageUrl: require("../../assets/t1.png")
}] },
error: function (data) {
this.products = [{
name: 'failed' + 'test',
imageUrl: require("../../assets/t1.png")
}]
}
});
}
}
}
</script>
Now when I run this I do get the alert window showing me that it did indeed fetch the data, however, it does not actually manage to update the object in question (product name remains loading data and not success test). If I move the code
this.products = [{
name: 'success' + 'test',
imageUrl: require("../../assets/t1.png")
}]
into the created: function() like so:
created: function () {
this.products = [{
name: 'success' + 'test',
imageUrl: require("../../assets/t1.png")
}]
this.fetchData();
}
it does actually update the data. So this means that both the code to fetch the data is accurate and the placeholder to update the data is functional, so why is the data not getting updated?
(note that the code to update the data is a placeholder).
in your fetchData function you have used 'this' keyword inside $.ajax() which can confuse compiler to which object you are referring so why not try this:
fetchData: function () {
let app = this;
$.ajax({
type: "GET",
timeout: 1200000,
url: 'api/test',
contentType: "application/json",
dataType: "text",
success: function (data) {
window.alert(data);
app.products = [{
name: 'success' + 'test',
imageUrl: require("../../assets/t1.png")
}] },
error: function (data) {
app.products = [{
name: 'failed' + 'test',
imageUrl: require("../../assets/t1.png")
}]
}
});
}

Merge two Arrays using underscore.js in AngularJS

I have two api requests and both gets a result of JSON. The first request is "account" request and second is "Container" request. Now:
Request for all Accounts (accountid: 1, name: account1, blabla)
Request for all Containers (accountid: 1, name: Container1, blabla)
This is the result JSON of Accounts:
account: [
{
accountId: "123456789",
fingerprint: null,
name: "Account2",
path: "accounts/123456789",
},
This is the result JSON of Containers:
{
accountId: "123456789",
containerId: "123****",
domainName: null,
fingerprint: "123*****",
name: "Container23",
path: "accounts/123456789/containers/123******",
publicId: "GTM-****"
},
As you can see the container result contains the accountid so im trying to merge those two results so it becomes this combined (container):
{
accountId: "123456789",
name: "Account2", <------ THIS is what i want to merge
containerId: "123****",
domainName: null,
fingerprint: "123*****",
name: "Container23",
path: "accounts/123456789/containers/123******",
publicId: "GTM-****"
},
Remember there are many containers and accounts not just one block.
What i have tried using underscore:
var mergedList = _.map($scope.GTMcontainers, function(data){
return _.extend(data, _.findWhere($scope.account, { id: data.accountId }));
});
console.log(mergedList);
Here is my AngularJS
function getContainer() {
$http.get("http://******")
.then(function (response) {
$scope.GTMcontainers = response.data;
console.log(response);
$scope.loading = false;
})
.then(function () {
$http.get("http://******")
.then(function (response2) {
$scope.account = response2.data;
console.log(response2);
var mergedList = _.map($scope.GTMcontainers, function(data){
return _.extend(data, _.findWhere($scope.account, { id: data.accountId }));
});
console.log(mergedList);
})
})
}
Using this underscore gives me exactly the same JSON result as i requested (no merge).
Hope some one has experience with this.
Thanks
Updated:
using simple javascript
var accounts = [
{
accountId: "123456789",
fingerprint: null,
name: "Account2",
path: "accounts/123456789",
},{
accountId: "123456780",
fingerprint: null,
name: "Account3",
path: "accounts/123456789",
}]
var containers =[{
accountId: "123456789",
containerId: "123****",
domainName: null,
fingerprint: "123*****",
name: "Container23",
path: "accounts/123456789/containers/123******",
publicId: "GTM-****"
},{
accountId: "123456780",
containerId: "123****",
domainName: null,
fingerprint: "123*****",
name: "Container24",
path: "accounts/123456789/containers/123******",
publicId: "GTM-****"
}]
var result=[];
containers.forEach(function(item){
var temp=accounts.find(function(d){return d.accountId == item.accountId});
if(temp)
item.name = temp.name;
result.push(item);
})
console.log(result);
I have faced that issue, I knew I have got responses, but data was not merged. So I have used callbacks.
function getContainer(callback) {
$http.get("http://******")
.then(function (response) {
$scope.GTMcontainers = response.data;
console.log(response);
$scope.loading = false;
})
.then(function () {
$http.get("http://******")
.then(function (response2) {
$scope.account = response2.data;
console.log(response2);
if(response && response2){
callback(response,response2);
}
})
})
}
At function call time--
getContainer(function(array1,array2){
if(array1 && array2 && array1.length>0 && array2.length>0){
var mergedList = _.map(array1, function(data){
return _.extend(data, _.findWhere(array2, { id: data.accountId }));
});
console.log(mergedList);
}
})

jQuery Autocomplete showing result label as undefined

The list is being filtered properly but the label is showing as undefined. When I select the item, the value is binded.
Below is my code along with the screenshots:
$(document).on('ready',function(){
$('#search').autocomplete({
source: function(req,res) {
$.ajax({
url: "/search",
dataType: "json",
type: "GET",
data: {
term: req.term
},
success: function(data) {
res($.map(data, function(item) {
return {
label: item.name,
value: item.id
};
}));
},
error: function(xhr) {
alert(xhr.status + ' : ' + xhr.statusText);
}
});
},
select: function(event, ui) {
}
});
});
Before Selection
After selection
I tried debugging the label and value using alert function. The values are perfect. I'm unable to figure out the error.
item.name
item.id
Here is the callback response:
[
{
"id":"1",
"name":"Android"
},
{
"id":"2",
"name":"Akira"
},
{
"id":"3",
"name":"Andy"
},
....
]
You are returning different property names in ajax success function.
Can you try to use these property names instead.
[
{
"label":"1",
"value":"Android"
},
....
]
$.ajax({
url: "url",
type: 'POST',
data: {
},
success: function (res) {
//console.log(res);
var obj = JSON.parse(res);
$('#od').html('<option value=""> Select</option>');
for (var i = 0, len = obj.length; i < len; i++){
$('#id').append('<option value='+ obj[i].item_id +'> '+ obj[i].item_name +'</option>');
}
}
});
here is my code for get all option you can try this

Loading data from ajax breaks functionality

I am trying to create a real-time filter on a table using knockoutjs.
I have managed to get everything to work when I statically create the observable array like this:
$(function() {
var assets = [
{id: "1", poster: "Pic010.jpg", name: "Asset1", category: "category1", type: "Movie", popup: "1" },
{id: "2", poster: "Pic06.jpg", name: "Asset2", category: "category2", type: "Movie", popup: "2" },
{id: "3", poster: "Pic04.jpg", name: "Asset3", category: "category1", type: "Pop-up", popup: "3" },
{id: "4", poster: "Pic07.jpg", name: "Asset4", category: "category2", type: "Pop-up", popup: "4" },
{id: "5", poster: "Pic011.jpg", name: "Asset1", category: "category3", type: "Promo", popup: "5" }
];
var viewModel = {
assets: ko.observableArray(assets),
query: ko.observable(''),
search: function(value) {
viewModel.assets.removeAll();
for(var x in assets) {
if(assets[x].name.toLowerCase().indexOf(value.toLowerCase()) >= 0) {
viewModel.assets.push(assets[x]);
}
}
}
};
viewModel.query.subscribe(viewModel.search);
ko.applyBindings(viewModel);
});
JSFiddle of working code: http://jsfiddle.net/7ZLdk/1/
Now when I try to load the observable array data via ajax like this:
var assets = [];
$.ajax({
url: '/Assets/getJson/',
type: "GET",
dataType: 'json',
success: function (data) {
console.log(data);
viewModel.assets(data);
}
});
the data is displayed correctly in the table when the page is loaded, but when I start typing in the search input, all the data disappears.
I would appreciate it if someone could explain what I am doing incorrectly in the AJAX load? TIA
You are better off creating a ViewModel function, so the viewmodel only accesses data within itself:
$(function() {
$.ajax({
url: '/Assets/getJson/',
type: "GET",
dataType: 'json',
contentType: "application/json",
success: function (data) {
console.log(data);
var viewModel = new ViewModel(data);
ko.applyBindings(viewModel);
}
});
});
function ViewModel(assets) {
var self = this;
self.assets = ko.observableArray(assets);
self.allAssets = assets;
self.query = ko.observable('');
self.search = function(value) {
self.assets.removeAll();
for(var x in self.allAssets) {
if(self.allAssets[x].name.toLowerCase().indexOf(value.toLowerCase()) >= 0) {
self.assets.push(self.allAssets[x]);
}
}
};
self.query.subscribe(self.search);
}
I have resolved the problem.
I was not populating the assets array. This is the updated ajax call:
$.ajax({
url: '/Assets/getJson/',
type: "GET",
dataType: 'json',
contentType: "application/json",
success: function (data) {
console.log(data);
viewModel.assets(data);
assets = data; // THIS WAS MISSING
}
});

Categories

Resources