Fill observable-fields-object by same fields-names object - javascript

I have object that all of its fields are observable (knockout.observable).
I have other regular object too, that its fields have the same names like the first-object-fields.
I want to insert into each field of the first object, the value of the match-field at the second object.
For example:
var first = {
a:ko.observable(),
b:ko.observable()
};
var second= {
a:'my'
b:'fields';
};
I want the first object to look like:
first = {
a:ko.observable('my'),
b:ko.observable('fields')
};
Yes, of course, I can do it by 'each' loop.
But, my question is:
Is there any build-in function that does it?

You can use the ko.mapping plugin:
var results = ko.mapping.fromJS(second, first);
See Documentation

Related

Check if an object contains a property called format in Javascript

I have an array of movie objects in a web application, and each object has properties for title(string),release year(int),rating(int) and genre(an array of string e.g ['Action','Sci-Fi],now some of the movie objects got a property for format(string) while others don't.All I need is help iterating through these objects and checking which objects don't have a format property and add the property to these objects and set the values with Film for those that do not...
Here is the js code i tried so far
var fractured={
title:"Fractured",
release:2019,
rating:8,
format:"digital",
genre:[
"Mystery","Sci-Fi","Western"]
};
var countdown={
title:"Countdown",
release:2018,
rating:5,
genre:["Sci-Fi","Mystery","Western"]
}
var bloodshot={
title:"Bloodshot",
release:2020,
rating:6,
format:"digital",
genre:["Sci-Fi","Action"]
}
var revenant={
title:"Revenant",
release:2015,
rating:3,
genre:["History","Western","Action"]
}
var crisis={
title:"Crisis",
release:2016,
rating:10,
genre:["Action","Drama","Reality"]
}
var life={
title:"Life",
release:2017,
rating:9,
format:"digital",
genre:["Sci-Fi","Action","Mystery"]
}
var nmovies=new Array(fractured,life,crisis,revenant,bloodshot,countdown);
//This line outputs the title property of the first object in nmovies;
console.log(nmovies[0].title);
//this is the iteration that needs to check if an object has a format property and add it with the value 'Film'
nmovies.forEach(myfunction());
function myfunction(item, index){
//Code to check please
}
Thank you for your input.
I am new to JavaScript but hopefully that works.
function myfunction(item, index) {
if (!item.hasOwnProperty("format")) {
item.format = "Film";
}
}

What is the correct way to handle this data using jQuery?

I have a list of html elements with data attributes, which I would like to assemble into a jQuery object and manipulate the values.
What is the best way to dynamically add these in an each loop so that I can easily access the data as so: data.name and data.name.prop?
I want all the naming conventions to be dynamic and based on the data.
I based my code on the top answer from here: How to create dynamically named JavaScript object properties?
So far I have:
$('.licences-list .data div').each(function(index) {
var data = {}
cats[$(this).find('p').data('cat')] = $(this).find('p').data('catname')
cats.push(data)
})
But when I try to iterate over the data array, like so:
$.each(cats, function(key, value){
$('<div class="card"><p>'+value+'</p></div>').appendTo('#commercial-licenses');
});
I just get [object Object] output... and I'm not sure why!
var data = {}
cats[$(this).find('p').data('cat')] = $(this).find('p').data('catname')
Each time you loop through, you're actually just adding an empty object (data) to your array (cats). You're then assigning a named property to that array (cats) which $.each has no idea about (it ignores them because it's iterating over an actual array).
My guess is you want an object map which is something like: var cats = { "f1": "feline 1", "f2": "feline " };
In that case what you want is:
var cats = {};
$('.licences-list .data div').each(function(index) {
cats[$(this).find('p').data('cat')] = $(this).find('p').data('catname')
})
If you want an array that contain more values than just strings (or whatever data you have added to the element), you create new objects each time and append them to the cats array:
var cats = [];
$('.licences-list .data div').each(function(index) {
cats.push({
'id': $(this).find('p').data('cat'),
'name': $(this).find('p').data('catname')
});
})
This will then give you an array that you can use $.each over, and access the values using: value.id, value.name
Don't over complicate it.
$('.div').attr('data-attribute', 'data-value');
using your example:
$('.licences-list .data div').attr('attribute-name', 'attribute-value');

ng-repeats, showing record while it's value is a part of field of another object

I've got objects 'ing' with a field named 'id' and another one called 'fObj' with a field named 'contain'.
By using ng-repeat i'd like to show only these 'ing' objects where ing.id is a part of fObj.contain
e.g.
ing=[{id: 1,field: value},{id:2, field: othervalue},{id:3, field: cat}];
fObj={field1: value1, field: value2, contain: ':1:3:'};
By having this contain value I'd like to show only ing's with id=1 and id=3
Yeah, I know there are two types of data (number and string) but even if i changed numbers to strings it still didn't work
I just dont't know how to make it works. It's probably some kind of custom filter, but I've tried couples and nothing happend.
I would be glad if you suggest me a solution.
Thanks
In your controller,
var ids = fObj.contain.split(':');
// the array for your ng-repeat
var displayIng = [];
// loop the objects, see if the id exists in the list of id's
// retrieved from the split
for(i = 0; i < ing.length; i++) {
if(ids.indexOf(ing.id.toString()) displayIng.push(ing[i]);
}
I would split the numbers out of fObj.contain; and use them as hashmap object keys for simple filtering of the array
var ing=[{id: 1},{id:2},{id:3}];
var fObj={contain: ':1:3:'};
var IDs = fObj.contain.split(':').reduce(function(a,c){
a[c]=true;
return a;
},{});
// produces {1:true,3:true}
var filtered = ing.filter(function(item){
return IDs[item.id];
});
console.log(filtered)

How to replace ' / ' with '-' inside ObservableArray ? Knockout js

Well i am trying to pass an observable array via ajax call to my controller but i get every value there except date . i get something like '01-01-01' etc .
I found the issue but unable to fix that as i dont know how to replace / with - .
My ObservableArray have around 10 list items each list item holds a many properties out of those startDate holds the date like ("23/10/2014") . i just need something like ("23-10-2014") .
Tought of posting my function's and more i hope thats not required in this case i believe .
Let me explain with bit of code and sample data :
function myarray()
{
var self=this;
self.startDate=ko.observable("");
self.name=ko.observable("");
self.place=ko.observable("");
}
MyObservableArray :
self.Main= ko.observableArray();
In between i do some stuff to load Data into self.Main and i am sending self.Main to controller having data like below :
self.Main[0] holds :
startDate() -->gives you "23/10/2014" //individual observables inside onservable array
name() --> "jhon"
place()--> "croatia"
Likely
self.Main[9] holds :
startDate() --> "29/05/2012"
name() --> "pop"
place()--> "usa"
I am trying like i want to alter the self.Main() and replace the startDate and use the same self.Main to send to my controller . Once after replacing in self.Main when i check date the / should be replaced with - .
Possible solution : i can use a different observable array and push all the VM's of Main into it but i am trying to do on self.Main without using other .
If someone can show some light it is much appreciated .
What I got that you are facing problem in escaping / in replace.
Try this
"(23/10/2014)".replace(/\//g,"-") //returns "(23-10-2014)"
I tried something for you using simple JS
var arr = [{date:"(23/10/2014)"},{date:"(23/10/2014)"},{date:"(23/10/2014)"},{date:"(23/10/2014)"}];
arr.forEach(function(obj){obj.date = obj.date.replace(/\//g,"-")});
console.log(arr) //will print date field as "(23-10-2014)" for all objects.
One solution would be to add a computed value that returns the array with the right values.
self.Main = ko.observableArray([...values here...]);
self.MainComputed = ko.computed(function() {
var computedArray = [];
self.Main().forEach(function(item) {
var newItem = myarray(); //Create a new item.
newItem.name(item.name());
newItem.place(item.place());
newItem.startDate(item.startDate().replace(/\//g,"-"));
computedArray.push(newItem);
});
return computedArray;
});
Then use the computed value in the places where you need the values with -.
I can think of two other ways to solve your issue, when taken into account that you want to use self.Main:
Replace the / with - before setting startDate on your item.
Change startDate to a computed value while storing the original value in another variable.
The first solution should be pretty straight forward (provided that it is a valid solution).
The second solution would look something like this:
function myarray()
{
var self=this;
self.originalStartDate = ko.observable("");
self.name = ko.observable("");
self.place = ko.observable("");
self.startDate = ko.computed(function() {
if(self.originalStartDate()) {
//We can only replace if the value is set.
return self.originalStartDate().replace(/\//g,"-");
}
else {
//If replace was not possible, we return the value as is.
return self.originalStartDate();
}
});
}
Now when you set the values you do something like:
var item = myarray();
item.originalStartDate = "01/01/2014";
Then when you get the value of startDate you would get "01-01-2014".
I haven't used Knockout.js but you can do this with a Javascript replace:
var str = [your array value] ;
var res = str.replace("/", "-");
For more information:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace

jQuery - Show variable, not text string

I have a variable being set as the .html(); of a <div />
The variable is the name of another variable. I want it to display the contents of the other variable, however it simply displays the name of the other variable.
How can I force it to show the variable contents rather than just a literal text string?
var clothing = 'dogeshop cryptoshop doge_clothing fyrstikken the_molly_machine peace_and_love moolah_market shibe_swag undieguys urban_graff kravshop got_doge mean_elephant the_dogedoor_store';
setInterval( function() {
var term = $("input").val();
$("#results").html(term);
}, 100);
When the user types 'clothing' into $("input"); the contents of the 'clothing' variable should be displayed in the $("#results"); <div />. Instead it just says 'clothing'.
Another way is to use object properties, like this
var obj = {};
obj.clothing = 'dogeshop cryptoshop doge_clothing fyrstikken the_molly_machine peace_and_love moolah_market shibe_swag undieguys urban_graff kravshop got_doge mean_elephant the_dogedoor_store';
setInterval( function() {
var term = $("input").val();
$("#results").html(obj[term]);
}, 100);
Here's the fiddle: http://jsfiddle.net/ZL7EQ/
The only way I know how to solve this is using eval:
$("#results").html(eval(term))
But you really shouldn't want to do that. :)
Use a dictionary.
// store strings in an object so you can look them up by key
var dict = {
clothing: 'dogeshop ...',
anotherKey: '...'
};
// update the result when the input changes
$('input').on('change', function() {
var result = dict[this.value]; // make sure the key exists
if (result) {
$('#results').val(result); // update the results
}
});
I use to make this mistake myself when working with jQuery.
Try instead:
$("#results").text(term);
Not sure what you have the interval for. You could just change the #results with a change event.

Categories

Resources