Ionic 2/Firebase - Reorder items from Firebase - firebase

I am currently making an Ionic 2 application. I would like the user to be able to reorder a list of items that is displayed from the database. However, I keep getting this error:
TypeError: array.splice is not a function at reorderArray
There seem to be a problem with my FirebaseListObservable but I do not know what it is. Any help is much appreciated!
Below is my code for the following:
export class ManageFavouritesPage {
fireAuth: any;
items: FirebaseListObservable<any[]>;
constructor(public navCtrl: NavController, public af: AngularFire, private toastCtrl: ToastController, public authData: AuthData) {
let userid = this.authData.getID();
this.items = af.database.list(`/users/${userid}/favourites`)
console.log(this.items);
}
reorderItems(indexes) {
this.items = reorderArray(this.items, indexes)
}

Related

Flutter - Mockito Firestore...get() - The method 'document' was called on null

for learning purposes I am trying to mock a Firestore controller class with Mockito.
firestore_controller.dart
import 'package:cloud_firestore/cloud_firestore.dart';
class FirestoreController implements FirestoreControllerInterface {
final Firestore firestoreApi;
FirestoreController({this.firestoreApi});
#override
Future<DocumentSnapshot> read() async {
final DocumentSnapshot document = await this.firestoreApi.collection('user').document('user_fooBar').get();
return document;
}
}
firestore_controller_test.dart
import 'package:flutter_test/flutter_test.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:mockito/mockito.dart';
import 'package:fooApp/Core/repositories/firebase/firestore_controller.dart';
class MockFirestoreBackend extends Mock implements Firestore {}
class MockDocumentSnapshot extends Mock implements DocumentSnapshot {}
void main() {
TestWidgetsFlutterBinding.ensureInitialized();
group("Firebase Controller", () {
final Firestore firestoreMock = MockFirestoreBackend();
final MockDocumentSnapshot mockDocumentSnapshot = MockDocumentSnapshot();
FirestoreController sut;
test("try to read a document", () async {
// Arrange
final Map<String, dynamic> _fakeResponse = {
'foo': 123,
'bar': 'foobar was here',
};
sut = FirestoreController(firestoreApi: firestoreMock); // INJECT MOCK
// Arrange: Mock
when(firestoreMock.collection('user').document('user_fooBar').get()).thenAnswer((_) => Future<MockDocumentSnapshot>.value(mockDocumentSnapshot));
when(mockDocumentSnapshot.data).thenReturn(_fakeResponse);
// Act
final fakeDocument = await sut.read();
});
});
}
🚨 Console Output 🚨
NoSuchMethodError: The method 'document' was called on null.
Receiver: null
Tried calling: document("user_fooBar")
sorry if the mistake is obvious, this is the first time I've used Mockito
Where's my error? What do I miss? Thanks a lot!
try this:
https://pub.dev/packages/cloud_firestore_mocks
A test I've done using it:
class MockFirestore extends Mock implements Firestore {}
class MockDocument extends Mock implements DocumentSnapshot {}
void main() {
final _tAppointmentModel = AppointmentModel(
appointmentID: kAppointmentID,
date: DateTime.parse("2020-12-05 20:18:04Z"),
description: "test description",
doctorID: kDoctorID,
hospitalID: kHospitalID,
infantID: kInfantID,
);
group('AppointmentModel tests: ', () {
final tAppointmentID = kAppointmentID;
final tInfantID = kInfantID;
final tDoctorID = kDoctorID;
final tHospitalID = kHospitalID;
test('should be a subclass of Appointment', () async {
expect(_tAppointmentModel, isA<Appointment>());
});
test('store and retrieve document from Firestore', () async {
final instance = MockFirestoreInstance();
await instance.collection('appointments').add({
'appointmentID': tAppointmentID,
'date': DateTime.parse("2020-12-05 20:18:04Z"),
'description': "test description",
'doctorID': tDoctorID,
'hospitalID': tHospitalID,
'infantID': tInfantID,
});
final snapshot = await instance.collection('appointments').getDocuments();
final String expected = _tAppointmentModel.props[0];
final String result = snapshot.documents[0].data['appointmentID'];
expect(expected, result);
});
});
}
So I think I've found why this is - it appears to be a bug(ette) in Mockito, in that it doesn't handle the "dot walk" from collection(any) to document() or getDocuments(). I fixed it like this:
declare five classes:
class MockFirebaseClient extends Mock implements Firestore {} //for your mock injection
class MockCollectionReference extends Mock implements CollectionReference {} //for when declaration
class MockQuerySnapshot extends Mock implements QuerySnapshot {} //for the thenAnswer return on collection of docs
class MockDocumentReference extends Mock implements DocumentReference {} //for single doc query
class MockDocumentSnapshot extends Mock implements DocumentSnapshot {} // for the thenAnswer return on single doc query
Do your setup etc - then the when clauses are just:
when(mockCollectionReference.getDocuments())
.thenAnswer((_) => Future.value(mockQuerySnapshot)); //for collection of docs query
when(mockDocumentReference.get())
.thenAnswer((_) => Future.value(mockDocumentSnapshot)); //for single doc query

Angular Http method not found

I've used this as core project for one of my project and I am stuck with it.
I trying to use the http method but it fails.
I've tried add the HttpClientModule to the app.module but still nothing.
The error that i get is :
app.ae014c5e7b696f87de83.bundle.js:107 ERROR TypeError:
Cannot read property 'method' of undefined
All I did in the app.component.ts file add
export class AppComponent extends BaseComponent implements OnInit {
constructor(
private readonly i18nStore: Store<I18NState>,
private readonly config: ConfigService,
private http: HttpClient,
#Inject(PLATFORM_ID) public platformId: Object
) {
super();
// TODO: ngx-i18n-router
// private readonly i18nRouter: I18NRouterService) {
}
ngOnInit(): void {
this.i18nStore.dispatch(new Init(this.config.getSettings('i18n')));
}
createUserA(): void {
this.http.get<any>('https://swapi.co/api/people/1')
.subscribe(data => console.log('data', data));
}
}
Bot get and post don't work.
I've imported :
import { HttpClient } from '#angular/common/http';
Add to your app.component.ts
contructor(private http : HttpClient) {}

Get a collection using user uid to generate Firestore reference

I want to set a firestore collection in a service to later return an observable of its documents
#Injectable()
export class ContactService {
private contactCollection: AngularFirestoreCollection<any>;
private contactDocument: AngularFirestoreDocument<any>;
constructor(
private authService: AuthService,
private afs: AngularFirestore
) {
this.authService.user
.subscribe(user => this.contactCollection = this.afs.collection(`directories/${user.uid}/contacts`));
}
getContacts(){
return this.contactCollection.valueChanges()
}
this works fine if i navigate to the route that displays the component that consume the service but if i visit directly the route or refresh the page the contactCollection is undefined.
Any ideas why is this happening?

Angular 2/4: How to call Web Apis via Http Post with parameters?

I'm a newbie with regards to Angular. I've looked at several places and most of the examples are extremely complicated. Is there something simple which I can start from? Something that calls a web api which accepts 2 parameter and returns an object
[HttpPost("GetHomePageData")]
public HomePageData GetHomePageData(int P1, int P2)
{
//
}
public class HomePageData
{
public int AddressCount { get; set; }
}
In Angular's official documentation you can see examples like this:
#Component(...)
export class MyComponent implements OnInit {
results: string[];
// Inject HttpClient into your component or service.
constructor(private http: HttpClient) {}
ngOnInit(): void {
// Make the HTTP request:
this.http.get('/api/items').subscribe(data => {
// Read the result field from the JSON response.
this.results = data['results'];
});
}
}

Ionic3 get firebase data too slow to list it

constructor(public navCtrl: NavController,public navParams : NavParams,
public modalCtrl:ModalController, private afAuth:AngularFireAuth, private afDatabase:AngularFireDatabase , public fb:FirebaseService) {
this.getDefaults();
this.selectedExercise=[];
console.log("home");
this.exercises=this.fb.getShoppingItems();
console.log(this.exercises);
at home.ts file,
at constructor, I get firebase data from firebase provider that I made to show it on list on html.
but the problem is that I logged it console.log(this.exercises) which is the data that I want to show on list, but it came null.
but after logged null, firebase provider get data from firebase and logged it
as you can see below.
I think browser should wait until firebase provider get data then should list it.
but don't know how to do it.
This is the way you should go
You need to change your getShoppingItems method to return a promise object like this
getShoppingItems(){
return new Promise<any>((resolve, reject) => {
this.db.list("/profile/user_id").subscribe(result =>{
resolve(result));
}
});
}
Your constructor method should get the result like this
constructor(
public navCtrl: NavController,
public navParams : NavParams,
public modalCtrl:ModalController,
private afAuth:AngularFireAuth,
private afDatabase:AngularFireDatabase ,
public fb:FirebaseService) {
this.getDefaults();
this.selectedExercise=[];
console.log("home");
//get your result like this
this.fb.getShoppingItems().then(result =>{
this.exercises = result;
console.log(this.exercises);
});
}
use the async pipe:
*ngFor="let item of exercises | async"
with
exercises = this.afd.list('...');

Resources