Meteor helpers modify output - angularjs

I need some help with meteor.
I created a publish in the server side and after subscription in the client side I added a helper to get my data.
this.helpers({
tags() {
var tags = Tag.find();
return tags;
}
})
What I need to do is add a Key called Cheked = true to tags.
How can I do this please ? because if I do it in the init it will not work since the suscription is not ready yet.
Thank you

You can use .map() to map the cursor and add a key to each document:
this.helpers({
tags() {
let tags = Tag.find().map(doc=>{
doc.checked = true;
return doc;
});
return tags;
}
})

Try with that way:
Template.myTemplateName.helpers({
tags(){
//You should use also find().fetch()
return Tag.find().fetch();
}
});
show your subs code.
If you want to add key to the object you should use
Tag.update(id,{$set: {keyName: value}}) on selected id or all elements.

Related

Displaying data from Firebase in React without arrays

I am new to both React and Firebase. I struggled a bit to get data from the database, even though the instructions on the Firebase website were pretty straightforward.
I managed to print data in the view by using this code:
Get data from DB and save it in state:
INSTRUMENTS_DB.once('value').then(function(snapshot) {
this.state.instruments.push(snapshot.val());
this.setState({
instruments: this.state.instruments
});
From Firebase, I receive and Object containing several objects, which correspond to the differen instruments, like shown in the following snippet:
Object {
Object {
name: "Electric guitar",
image: "img/guitar.svg"
}
Object {
name: "Bass guitar",
image: "img/bass.svg"
}
// and so on..
}
Currently, I print data by populating an array like this:
var rows = [];
for (var obj in this.state.instruments[0]) {
rows.push(<Instrument name={this.state.instruments[0][obj].name}
image={this.state.instruments[0][obj].image}/>);
}
I feel like there's a better way to do it, can somedody give a hint? Thanks
I user firebase a lot and mu solution is little ES6 helper function
const toArray = function (firebaseObj) {
return Object.keys(firebaseObj).map((key)=> {
return Object.assign(firebaseObj[key], {key});
})
};
I also assign the firebase key to object key property, so later I can work with the keys.
The native map function only works for arrays, so using directly it on this object won't work.
What you can do instead is:
Call the map function on the keys of your object using Object.keys():
getInstrumentRows() {
const instruments = this.state.instruments;
Object.keys(instruments).map((key, index) => {
let instrument = instruments[key];
// You can now use instrument.name and instrument.image
return <Instrument name={instrument.name} image={instrument.image}/>
});
}
Alternatively, you can also import the lodash library and use its map method which would allow you to refactor the above code into:
getInstrumentRowsUsingLodash() {
const instruments = this.state.instruments;
_.map(instruments, (key, index) => {
let instrument = instruments[key];
// You can now use instrument.name and instrument.image
return <Instrument name={instrument.name} image={instrument.image}/>
});
}
Side note:
When you retrieve you data from Firebase you attempt to update the state directly with a call on this.state.instruments. The state in React should be treated as Immutable and should not be mutated with direct calls to it like push.
I would use map function:
_getInstrumentRows() {
const instruments = this.state.instruments[0];
if (instruments) {
return instruments.map((instrument) =>
<Instrument name={instrument.name}
image={instrument.image}/>);
}
}
In your render() method you just use {_getInstrumentRows()} wherever you need it.

Angular2 Tutorial: How is the ID variable in this section being auto incremented?

In This Section of the Angular2 Tutorial there is functionality to add new items to the array. When added, the ID is automatically incremented but I can't figure out what process is doing that.
I know that Arrays.push() returns the length of the array, is that length automatically inserted into the id variable in the Hero class?
In hero.services.ts there is this block of code to create a hero:
create(name: string): Promise<Hero> {
return this.http
.post(this.heroesUrl, JSON.stringify({name: name}), {headers: this.headers})
.toPromise()
.then(res => res.json().data)
.catch(this.handleError);
}
In the heroes.component.ts there is the add
add(name: string): void {
name = name.trim();
if (!name) { return; }
this.heroService.create(name)
.then(hero => {
this.heroes.push(hero);
this.selectedHero = null;
});
}
The tutorial is using the angular 2 in-memory-web-api library. It is handling the post that is being made to the heroes url. The handler can be seen in this file on line 328:
https://github.com/angular/in-memory-web-api/blob/master/in-memory-backend.service.js
Inside that handler the id is generated via a call to the genId function whose implementation is on line 257:
InMemoryBackendService.prototype.genId = function (collection) {
// assumes numeric ids
var maxId = 0;
collection.reduce(function (prev, item) {
maxId = Math.max(maxId, typeof item.id === 'number' ? item.id : maxId);
}, null);
return maxId + 1;
};
It uses the default functionality of InMemoryDbService .
You can find the mock/reference in app/in-memory-dataservice.ts
import { InMemoryDbService } from 'angular2-in-memory-web-api
The angular source for the service can be found here: in-memory-backend.service.t (line 326)
In the create method of the service, a web api gets called and posted the hero's name to it, returning a full hero object with id and name fields.
So I guess the incrementing and "saving" happens behind the curtains at that web api.

Auto-adding new item - Angular UI query

I'm adding a 'new stories' feature to a website for authors to contribute work to. The function below allows stories to be created and added to the author's profile but doesn't auto-add them to a list (ie I have to refresh the browser for this to work. Does anyone know if there is a way to do this (I've tried changing state back to 'authorprofile' but that didn't work).
self.addStory = function() {
var authorId = tokenService.getAuthor()._id;
console.log(authorId);
var data = {
story: self.currentStory,
authorId: authorId
}
Story.save(data, function(story) {
console.log("saving: " + story);
Story.put(data, function(story){
console.log("story added");
})
// auto-add new stories here
$state.go('authorprofile');
})
}
Assuming the list of stories is stored in a 'stories' variable on the scope:
// auto-add new stories here
$scope.stories.push(data);
Add new story into the array using in the success function using push method.
Story.save(data, function(story) {
//Add stories to the array
$scope.stories.push(story);
Story.put(data, function(story){
console.log("story added");
})
// auto-add new stories here
$state.go('authorprofile');
})

How to set dynamic variable name in Angularjs controller

This is my controller code :
var selectableFields = ["customerName", "customerAddress"];
angular.forEach(selectableFields, function(field, key) {
var value = $.jStorage.get(field); //using jStore to get the values
$scope.field=value;
});
The objective is to be able to access {{customerName}} and {{customerAddress}} in the view.
Can anyone please tell me what is the correct way of doing this?
Use $scope[field] = value; instead.
With $scope.field, you're creating a new attribute named field.
var pages=["kedi","köpek","tavşan","ayi"]
pages.map(page =>{
$rootScope["adChangeUrl"+page]="dene.com"
$rootScope["imgSrc"+page]="images/deneme.png"
$rootScope["imgAdTitle"+page]="deneme.com"
$rootScope["imgAdAlt"+page]="https://deneme.com/"
}
)
//console.log Output
adChangeUrlayi: "dene.com"
adChangeUrlkedi: "dene.com"
adChangeUrlköpek: "dene.com"
adChangeUrltavşan: "dene.com"
imgAdAltayi: "https://deneme1.com/"
imgAdAltkedi: "https://deneme1.com/"
imgAdAltköpek: "https://deneme1.com/"
imgAdAlttavşan: "https://deneme1.com/"
imgAdTitleayi: "deneme.com"
imgAdTitlekedi: "deneme.com"
imgAdTitleköpek: "deneme.com"
imgAdTitletavşan: "deneme.com"
imgSrcayi: "images/deneme.png"
imgSrckedi: "images/deneme.png"
imgSrcköpek: "images/deneme.png"
imgSrctavşan: "images/deneme.png"

Backbone - trying to make a filter on a collection with nested object

i'm trying to filter a collection which has models with some nested object. Unfortunately, my result are always empty.
So my models returned in the collection are build like this:
My goal is simple:
I have a view with a list of tag and a content view with all the questions. When a user click on tag, for example, "c#", i want to filter my collection to just return questions with tag "c#"
Before i was doing a fetch on my server and it was working fine, but it was not optimize.
I already have a collection with all the questions so why make a new call, a filter is a better solution i think.
But i didn't succeded with my filter and i don't know if it's possible to do. For now i put my filter in my router because it's more easy to test.
i can't make a filter like this because i have an array of object
getQuestionsByTags: function(query) {
var test = this.questionsCollection.filter(function(model) {
return model.attributes.tags.name == query;
})
console.log('result');
console.log(test);
},
So i was thinking to make a loop but my result is always an empty array.
getQuestionsByTags: function(query) {
var test = this.questionsCollection.filter(function(model) {
_.each(model.attributes.tags, function(tag) {
return tag.name == query;
})
})
console.log('result');
console.log(test);
},
It's maybe simple, but i don't know what to do.
Thanks in advance :)
i've just found a solution that work.
getQuestionsByTags: function(query) {
var flag;
var test2 = this.questionsCollection.filter(function(model) {
flag = false;
_.each(model.attributes.tags, function(tag) {
if(tag.name == query) {
flag = true;
}
})
if(flag) {
return model.attributes;
}
})
console.log('result');
console.log(test2);
},
i put a flag. If he turn true inside the loop, the model has this tag so i return it.
I think it's not very conventional, so if someone have another solution, feel free to post it :)

Resources